@thepayulink/checkout 2.1.3 → 2.1.4

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.
@@ -335,4 +335,4 @@ var E=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var le=Object
335
335
  <input class="pl-vpa" id="pl-vpa" placeholder="example@okhdfcbank" autocomplete="off" spellcheck="false">
336
336
  <button class="pl-verify" id="pl-verify">Verify and Pay</button>
337
337
  </div>
338
- <div id="pl-status" class="pl-pendrow"><span class="pl-mini-spin"></span> Waiting for payment\u2026</div>`}function N(e,t){if(e==="contact")t.querySelector("#pl-continue").onclick=()=>{let n=t.querySelector("#pl-name").value.trim(),s=t.querySelector("#pl-mobile").value.replace(/\D/g,""),v=t.querySelector("#pl-email").value.trim(),q=t.querySelector("#pl-cerr");if(n.length<2)return q.textContent="Please enter your name";if(s.length!==10)return q.textContent="Enter a valid 10-digit mobile number";l.customer={name:n,mobile:s,email:v},i("options")};else if(e==="options"){t.querySelectorAll(".pl-navitem").forEach(s=>s.onclick=()=>{s.dataset.m!=="upi"&&C("Coming soon \u2014 please pay via UPI / QR for now")});let n=t.querySelector("#pl-verify");n&&(n.onclick=()=>{let s=(t.querySelector("#pl-vpa").value||"").trim();if(!/^[\w.\-]{2,}@[a-zA-Z]{2,}$/.test(s))return t.querySelector("#pl-vpa").focus(),C("Enter a valid UPI ID, e.g. name@okhdfcbank");let v=l.order&&(l.order.upi_intent_url||l.order.payment_link);v&&/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent)?location.href=v:C("Scan the QR with your phone\u2019s UPI app to complete the payment.")}),B(),P(!0)}}let $=!1;async function P(e){if(e||i("options"),l.order){L();return}if(!$){$=!0;try{l.customer||(l.customer={name:a.prefill.name||"Customer",mobile:(a.prefill.contact||"").replace(/\D/g,""),email:a.prefill.email||""}),l.order=await a.createOrder(l.customer),L(),V()}catch(t){let n=p.querySelector("#pl-qr");if(n){n.innerHTML=`<div class="pl-qrerr"><span>${f(t.message||"Could not start payment")}</span><button class="pl-retry" id="pl-retry">Try again</button></div>`;let s=n.querySelector("#pl-retry");s&&(s.onclick=()=>{$=!1,n.innerHTML='<div class="pl-qrloading"></div>',P(!0)})}}finally{$=!1}}}function L(){let e=l.order;if(!e)return;Y(e);let t=p.querySelector("#pl-qr");t&&(e.qr_data_url?t.innerHTML=`<img src="${e.qr_data_url}" alt="UPI QR">`:t.innerHTML='<div class="pl-qrerr"><span>QR unavailable \u2014 use a UPI app below</span></div>');let n=e.upi_intent_url||e.payment_link||"#",s=p.querySelector("#pl-applist");s&&s.querySelectorAll(".pl-uapp").forEach(v=>{v.setAttribute("href",n),v.setAttribute("target","_blank"),v.setAttribute("rel","noopener")}),B()}function Y(e){e&&e.expires_at&&e.server_now?l.expiryMs=Date.now()+Math.max(0,e.expires_at-e.server_now):l.expiryMs||(l.expiryMs=Date.now()+5*60*1e3)}function T(){if(l.done)return;let e=p.querySelector("#pl-qr");e&&(e.innerHTML='<div class="pl-qrerr"><span>QR code expired</span><button class="pl-retry" id="pl-regen">Generate new QR</button></div>');let t=p.querySelector("#pl-regen");t&&(t.onclick=H);let n=p.querySelector("#pl-timer");n&&(n.textContent="Expired");let s=p.querySelector(".pl-validrow");s&&s.classList.add("pl-expired")}function H(){if(l.stop){try{l.stop()}catch{}l.stop=null}l.order=null,l.expiryMs=null,$=!1;let e=p.querySelector(".pl-validrow");e&&e.classList.remove("pl-expired");let t=p.querySelector("#pl-qr");t&&(t.innerHTML='<div class="pl-qrloading"></div>'),P(!0)}function V(){!l.order||l.stop||(l.stop=a.watchOrder(l.order.merchant_order_no,e=>{!e||typeof e.status!="number"||(e.status===0?(l.utr=e.utr||l.utr,Q()):e.status===3?(clearInterval(l.timer),l.expiryMs=Date.now(),T(),j("failed","QR expired \u2014 generate a new one")):[1,4].includes(e.status)?j("failed","Payment "+(e.status_label||"failed").toLowerCase()):e.status===6&&j("pending","Processing payment\u2026"))}))}function j(e,t){let n=p.querySelector("#pl-status");n&&(n.className=e==="failed"?"pl-pendrow pl-fail":"pl-pendrow",n.innerHTML=(e==="pending"?'<span class="pl-mini-spin"></span> ':"")+f(t))}function Q(){l.done||(l.done=!0,clearInterval(l.timer),i("success"),a.onSuccess&&a.onSuccess({merchant_order_no:l.order.merchant_order_no,utr:l.utr,amount:a.amount}),l.utr||X())}async function X(){for(let e=0;e<10&&!l.utr;e++){await new Promise(t=>setTimeout(t,4e3));try{let t=await fetch(`${o}/api/order/${l.order.merchant_order_no}`).then(n=>n.json());if(t.utr){l.utr=t.utr;let n=p.querySelector("#pl-pid");n&&l.screen==="success"&&n.insertAdjacentHTML("afterend",`<div class="pl-pid pl-utr">UTR ${f(t.utr)}</div>`);break}}catch{}}}function B(){clearInterval(l.timer);let e=()=>{let t=p.querySelector("#pl-timer");if(!t)return;if(!l.expiryMs){t.textContent="Valid 5:00";return}let n=Math.max(0,Math.round((l.expiryMs-Date.now())/1e3));t.textContent=n>0?"Valid "+pe(n):"Expired",n<=0&&(clearInterval(l.timer),T())};e(),l.timer=setInterval(e,1e3)}function C(e){let t=document.getElementById("pl-toast");t||(t=document.createElement("div"),t.id="pl-toast",document.body.appendChild(t)),t.textContent=e,t.classList.add("pl-show"),clearTimeout(t._t),t._t=setTimeout(()=>t.classList.remove("pl-show"),2600)}return i("loader"),setTimeout(()=>{let e=a.prefill||{};e.name&&(e.contact||"").replace(/\D/g,"").length===10?(l.customer={name:e.name,mobile:e.contact.replace(/\D/g,""),email:e.email||""},i("options")):i("contact");let t=p.querySelector("#pl-splash");t&&(t.classList.add("pl-splash-hide"),setTimeout(()=>t.remove(),450))},1600),{close:d}}var D={apiBase:"https://payulink.io/api",assetBase:"https://assetcdn.payulink.io/checkout/v1/assets",name:null,logo:null,brandColor:null,pollMs:2500},w=class a{constructor(o={}){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("PayuLink checkout runs in the browser only. On React Native use @thepayulink/checkout-react-native; on a server use @thepayulink/server.");let r=o.key||o.keyId||o.key_id;if(!r)throw new Error("PayuLink: `key` (your publishable pl_live_\u2026 / pl_test_\u2026 key) is required");if(/^pl_(live|test)_/.test(r)||console.warn("PayuLink: `key` should look like pl_live_\u2026 or pl_test_\u2026"),o.keySecret||o.key_secret)throw new Error("PayuLink: never pass a key_secret to the browser SDK. It belongs on your server only.");this.options=Object.assign({},D,o,{key:r})}open(o={}){let r=Object.assign({},this.options,o),y=String(r.apiBase||"").replace(/\/$/,""),h=String(r.assetBase||`${y}/assets`).replace(/\/$/,""),l=r.order_id||r.orderId;if(!l)throw new Error("PayuLink: `order_id` is required. Create it on your server with POST /v1/orders.");let p=d=>{typeof r.onError=="function"?r.onError(d):console.error("PayuLink:",d.message||d)},x=null,S=null,I=async d=>{var g,_,c;let u=await fetch(`${y}/v1/checkout/session`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key_id:r.key,order_id:l,customer:d?{name:d.name,contact:d.mobile||d.contact,email:d.email}:void 0})}),i=await u.json().catch(()=>({}));if(!u.ok){let M=new Error(((g=i==null?void 0:i.error)==null?void 0:g.description)||`Could not start payment (HTTP ${u.status})`);throw M.code=(_=i==null?void 0:i.error)==null?void 0:_.code,M.retriable=((c=i==null?void 0:i.error)==null?void 0:c.code)==="GATEWAY_BUSY",M}return x=i,{merchant_order_no:i.order_id,amount:i.amount/100,upi_intent_url:i.upi_intent_url,payment_link:i.payment_link,qr_data_url:i.qr_data_url||null,qr_unavailable_reason:i.qr_unavailable_reason||null,qr_retriable:i.qr_retriable===!0,expires_at:i.expires_at?i.expires_at*1e3:null,server_now:Date.now()}},z=(d,u)=>{let i=async()=>{if(x!=null&&x.session_token)try{let c=await(await fetch(`${y}/v1/checkout/session/${encodeURIComponent(x.session_token)}`)).json().catch(()=>({}));c.status==="paid"&&c.payulink_signature&&(S={payulink_order_id:c.payulink_order_id,payulink_payment_id:c.payulink_payment_id,payulink_signature:c.payulink_signature,utr:c.utr||null,amount:c.amount}),u({status:c.status==="paid"?0:c.status==="failed"?1:c.status==="expired"?3:2,status_label:String(c.status||"pending").toUpperCase(),utr:c.utr||null})}catch{}},g=setInterval(i,r.pollMs||D.pollMs);return i(),()=>clearInterval(g)},k={_inner:null,close(){var d;(d=this._inner)==null||d.close()}};return fetch(`${y}/v1/checkout/order/${encodeURIComponent(l)}?key_id=${encodeURIComponent(r.key)}`).then(async d=>{var i;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(((i=u==null?void 0:u.error)==null?void 0:i.description)||"Unknown or expired order");k._inner=A(Object.assign({},{apiBase:y,assetBase:h,name:r.name||u.merchant_name,logo:r.logo||`${h}/payulink-logo.png`,brandColor:r.brandColor,note:r.note,prefill:r.prefill||{},amount:u.amount/100,description:r.description||r.item||u.merchant_name,createOrder:I,watchOrder:z,onSuccess:()=>{let g=S||{payulink_order_id:(x==null?void 0:x.order_id)||l,payulink_payment_id:null,payulink_signature:null};typeof r.handler=="function"&&r.handler(g),typeof r.onSuccess=="function"&&r.onSuccess(g)},onDismiss:()=>{typeof r.onDismiss=="function"&&r.onDismiss()},onError:p}))}).catch(p),k}static open(o={}){return new a(o).open(o)}};typeof window!="undefined"&&(window.PayuLink=w,window.PayulinkCheckout=w);
338
+ <div id="pl-status" class="pl-pendrow"><span class="pl-mini-spin"></span> Waiting for payment\u2026</div>`}function N(e,t){if(e==="contact")t.querySelector("#pl-continue").onclick=()=>{let n=t.querySelector("#pl-name").value.trim(),s=t.querySelector("#pl-mobile").value.replace(/\D/g,""),v=t.querySelector("#pl-email").value.trim(),q=t.querySelector("#pl-cerr");if(n.length<2)return q.textContent="Please enter your name";if(s.length!==10)return q.textContent="Enter a valid 10-digit mobile number";l.customer={name:n,mobile:s,email:v},i("options")};else if(e==="options"){t.querySelectorAll(".pl-navitem").forEach(s=>s.onclick=()=>{s.dataset.m!=="upi"&&C("Coming soon \u2014 please pay via UPI / QR for now")});let n=t.querySelector("#pl-verify");n&&(n.onclick=()=>{let s=(t.querySelector("#pl-vpa").value||"").trim();if(!/^[\w.\-]{2,}@[a-zA-Z]{2,}$/.test(s))return t.querySelector("#pl-vpa").focus(),C("Enter a valid UPI ID, e.g. name@okhdfcbank");let v=l.order&&(l.order.upi_intent_url||l.order.payment_link);v&&/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent)?location.href=v:C("Scan the QR with your phone\u2019s UPI app to complete the payment.")}),B(),P(!0)}}let $=!1;async function P(e){if(e||i("options"),l.order){L();return}if(!$){$=!0;try{l.customer||(l.customer={name:a.prefill.name||"Customer",mobile:(a.prefill.contact||"").replace(/\D/g,""),email:a.prefill.email||""}),l.order=await a.createOrder(l.customer),L(),V()}catch(t){let n=p.querySelector("#pl-qr");if(n){n.innerHTML=`<div class="pl-qrerr"><span>${f(t.message||"Could not start payment")}</span><button class="pl-retry" id="pl-retry">Try again</button></div>`;let s=n.querySelector("#pl-retry");s&&(s.onclick=()=>{$=!1,n.innerHTML='<div class="pl-qrloading"></div>',P(!0)})}}finally{$=!1}}}function L(){let e=l.order;if(!e)return;Y(e);let t=p.querySelector("#pl-qr");t&&(e.qr_data_url?t.innerHTML=`<img src="${e.qr_data_url}" alt="UPI QR">`:t.innerHTML=`<div class="pl-qrerr"><span>${f(e.qr_unavailable_reason||"QR unavailable \u2014 use a UPI app below")}</span></div>`);let n=e.upi_intent_url||e.payment_link||"#",s=p.querySelector("#pl-applist");s&&s.querySelectorAll(".pl-uapp").forEach(v=>{v.setAttribute("href",n),v.setAttribute("target","_blank"),v.setAttribute("rel","noopener")}),B()}function Y(e){e&&e.expires_at&&e.server_now?l.expiryMs=Date.now()+Math.max(0,e.expires_at-e.server_now):l.expiryMs||(l.expiryMs=Date.now()+5*60*1e3)}function T(){if(l.done)return;let e=p.querySelector("#pl-qr");e&&(e.innerHTML='<div class="pl-qrerr"><span>QR code expired</span><button class="pl-retry" id="pl-regen">Generate new QR</button></div>');let t=p.querySelector("#pl-regen");t&&(t.onclick=H);let n=p.querySelector("#pl-timer");n&&(n.textContent="Expired");let s=p.querySelector(".pl-validrow");s&&s.classList.add("pl-expired")}function H(){if(l.stop){try{l.stop()}catch{}l.stop=null}l.order=null,l.expiryMs=null,$=!1;let e=p.querySelector(".pl-validrow");e&&e.classList.remove("pl-expired");let t=p.querySelector("#pl-qr");t&&(t.innerHTML='<div class="pl-qrloading"></div>'),P(!0)}function V(){!l.order||l.stop||(l.stop=a.watchOrder(l.order.merchant_order_no,e=>{!e||typeof e.status!="number"||(e.status===0?(l.utr=e.utr||l.utr,Q()):e.status===3?(clearInterval(l.timer),l.expiryMs=Date.now(),T(),j("failed","QR expired \u2014 generate a new one")):[1,4].includes(e.status)?j("failed","Payment "+(e.status_label||"failed").toLowerCase()):e.status===6&&j("pending","Processing payment\u2026"))}))}function j(e,t){let n=p.querySelector("#pl-status");n&&(n.className=e==="failed"?"pl-pendrow pl-fail":"pl-pendrow",n.innerHTML=(e==="pending"?'<span class="pl-mini-spin"></span> ':"")+f(t))}function Q(){l.done||(l.done=!0,clearInterval(l.timer),i("success"),a.onSuccess&&a.onSuccess({merchant_order_no:l.order.merchant_order_no,utr:l.utr,amount:a.amount}),l.utr||X())}async function X(){for(let e=0;e<10&&!l.utr;e++){await new Promise(t=>setTimeout(t,4e3));try{let t=await fetch(`${o}/api/order/${l.order.merchant_order_no}`).then(n=>n.json());if(t.utr){l.utr=t.utr;let n=p.querySelector("#pl-pid");n&&l.screen==="success"&&n.insertAdjacentHTML("afterend",`<div class="pl-pid pl-utr">UTR ${f(t.utr)}</div>`);break}}catch{}}}function B(){clearInterval(l.timer);let e=()=>{let t=p.querySelector("#pl-timer");if(!t)return;if(!l.expiryMs){t.textContent="Valid 5:00";return}let n=Math.max(0,Math.round((l.expiryMs-Date.now())/1e3));t.textContent=n>0?"Valid "+pe(n):"Expired",n<=0&&(clearInterval(l.timer),T())};e(),l.timer=setInterval(e,1e3)}function C(e){let t=document.getElementById("pl-toast");t||(t=document.createElement("div"),t.id="pl-toast",document.body.appendChild(t)),t.textContent=e,t.classList.add("pl-show"),clearTimeout(t._t),t._t=setTimeout(()=>t.classList.remove("pl-show"),2600)}return i("loader"),setTimeout(()=>{let e=a.prefill||{};e.name&&(e.contact||"").replace(/\D/g,"").length===10?(l.customer={name:e.name,mobile:e.contact.replace(/\D/g,""),email:e.email||""},i("options")):i("contact");let t=p.querySelector("#pl-splash");t&&(t.classList.add("pl-splash-hide"),setTimeout(()=>t.remove(),450))},1600),{close:d}}var D={apiBase:"https://payulink.io/api",assetBase:"https://assetcdn.payulink.io/checkout/v1/assets",name:null,logo:null,brandColor:null,pollMs:2500},w=class a{constructor(o={}){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("PayuLink checkout runs in the browser only. On React Native use @thepayulink/checkout-react-native; on a server use @thepayulink/server.");let r=o.key||o.keyId||o.key_id;if(!r)throw new Error("PayuLink: `key` (your publishable pl_live_\u2026 / pl_test_\u2026 key) is required");if(/^pl_(live|test)_/.test(r)||console.warn("PayuLink: `key` should look like pl_live_\u2026 or pl_test_\u2026"),o.keySecret||o.key_secret)throw new Error("PayuLink: never pass a key_secret to the browser SDK. It belongs on your server only.");this.options=Object.assign({},D,o,{key:r})}open(o={}){let r=Object.assign({},this.options,o),y=String(r.apiBase||"").replace(/\/$/,""),h=String(r.assetBase||`${y}/assets`).replace(/\/$/,""),l=r.order_id||r.orderId;if(!l)throw new Error("PayuLink: `order_id` is required. Create it on your server with POST /v1/orders.");let p=d=>{typeof r.onError=="function"?r.onError(d):console.error("PayuLink:",d.message||d)},x=null,S=null,I=async d=>{var g,_,c;let u=await fetch(`${y}/v1/checkout/session`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key_id:r.key,order_id:l,customer:d?{name:d.name,contact:d.mobile||d.contact,email:d.email}:void 0})}),i=await u.json().catch(()=>({}));if(!u.ok){let M=new Error(((g=i==null?void 0:i.error)==null?void 0:g.description)||`Could not start payment (HTTP ${u.status})`);throw M.code=(_=i==null?void 0:i.error)==null?void 0:_.code,M.retriable=((c=i==null?void 0:i.error)==null?void 0:c.code)==="GATEWAY_BUSY",M}return x=i,{merchant_order_no:i.order_id,amount:i.amount/100,upi_intent_url:i.upi_intent_url,payment_link:i.payment_link,qr_data_url:i.qr_data_url||null,qr_unavailable_reason:i.qr_unavailable_reason||null,qr_retriable:i.qr_retriable===!0,expires_at:i.expires_at?i.expires_at*1e3:null,server_now:Date.now()}},z=(d,u)=>{let i=async()=>{if(x!=null&&x.session_token)try{let c=await(await fetch(`${y}/v1/checkout/session/${encodeURIComponent(x.session_token)}`)).json().catch(()=>({}));c.status==="paid"&&c.payulink_signature&&(S={payulink_order_id:c.payulink_order_id,payulink_payment_id:c.payulink_payment_id,payulink_signature:c.payulink_signature,utr:c.utr||null,amount:c.amount}),u({status:c.status==="paid"?0:c.status==="failed"?1:c.status==="expired"?3:2,status_label:String(c.status||"pending").toUpperCase(),utr:c.utr||null})}catch{}},g=setInterval(i,r.pollMs||D.pollMs);return i(),()=>clearInterval(g)},k={_inner:null,close(){var d;(d=this._inner)==null||d.close()}};return fetch(`${y}/v1/checkout/order/${encodeURIComponent(l)}?key_id=${encodeURIComponent(r.key)}`).then(async d=>{var i;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(((i=u==null?void 0:u.error)==null?void 0:i.description)||"Unknown or expired order");k._inner=A(Object.assign({},{apiBase:y,assetBase:h,name:r.name||u.merchant_name,logo:r.logo||`${h}/payulink-logo.png`,brandColor:r.brandColor,note:r.note,prefill:r.prefill||{},amount:u.amount/100,description:r.description||r.item||u.merchant_name,createOrder:I,watchOrder:z,onSuccess:()=>{let g=S||{payulink_order_id:(x==null?void 0:x.order_id)||l,payulink_payment_id:null,payulink_signature:null};typeof r.handler=="function"&&r.handler(g),typeof r.onSuccess=="function"&&r.onSuccess(g)},onDismiss:()=>{typeof r.onDismiss=="function"&&r.onDismiss()},onError:p}))}).catch(p),k}static open(o={}){return new a(o).open(o)}};typeof window!="undefined"&&(window.PayuLink=w,window.PayulinkCheckout=w);
@@ -335,4 +335,4 @@ var K=`
335
335
  <input class="pl-vpa" id="pl-vpa" placeholder="example@okhdfcbank" autocomplete="off" spellcheck="false">
336
336
  <button class="pl-verify" id="pl-verify">Verify and Pay</button>
337
337
  </div>
338
- <div id="pl-status" class="pl-pendrow"><span class="pl-mini-spin"></span> Waiting for payment\u2026</div>`}function D(e,a){if(e==="contact")a.querySelector("#pl-continue").onclick=()=>{let o=a.querySelector("#pl-name").value.trim(),p=a.querySelector("#pl-mobile").value.replace(/\D/g,""),v=a.querySelector("#pl-email").value.trim(),$=a.querySelector("#pl-cerr");if(o.length<2)return $.textContent="Please enter your name";if(p.length!==10)return $.textContent="Enter a valid 10-digit mobile number";l.customer={name:o,mobile:p,email:v},r("options")};else if(e==="options"){a.querySelectorAll(".pl-navitem").forEach(p=>p.onclick=()=>{p.dataset.m!=="upi"&&C("Coming soon \u2014 please pay via UPI / QR for now")});let o=a.querySelector("#pl-verify");o&&(o.onclick=()=>{let p=(a.querySelector("#pl-vpa").value||"").trim();if(!/^[\w.\-]{2,}@[a-zA-Z]{2,}$/.test(p))return a.querySelector("#pl-vpa").focus(),C("Enter a valid UPI ID, e.g. name@okhdfcbank");let v=l.order&&(l.order.upi_intent_url||l.order.payment_link);v&&/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent)?location.href=v:C("Scan the QR with your phone\u2019s UPI app to complete the payment.")}),T(),P(!0)}}let M=!1;async function P(e){if(e||r("options"),l.order){E();return}if(!M){M=!0;try{l.customer||(l.customer={name:t.prefill.name||"Customer",mobile:(t.prefill.contact||"").replace(/\D/g,""),email:t.prefill.email||""}),l.order=await t.createOrder(l.customer),E(),H()}catch(a){let o=n.querySelector("#pl-qr");if(o){o.innerHTML=`<div class="pl-qrerr"><span>${f(a.message||"Could not start payment")}</span><button class="pl-retry" id="pl-retry">Try again</button></div>`;let p=o.querySelector("#pl-retry");p&&(p.onclick=()=>{M=!1,o.innerHTML='<div class="pl-qrloading"></div>',P(!0)})}}finally{M=!1}}}function E(){let e=l.order;if(!e)return;N(e);let a=n.querySelector("#pl-qr");a&&(e.qr_data_url?a.innerHTML=`<img src="${e.qr_data_url}" alt="UPI QR">`:a.innerHTML='<div class="pl-qrerr"><span>QR unavailable \u2014 use a UPI app below</span></div>');let o=e.upi_intent_url||e.payment_link||"#",p=n.querySelector("#pl-applist");p&&p.querySelectorAll(".pl-uapp").forEach(v=>{v.setAttribute("href",o),v.setAttribute("target","_blank"),v.setAttribute("rel","noopener")}),T()}function N(e){e&&e.expires_at&&e.server_now?l.expiryMs=Date.now()+Math.max(0,e.expires_at-e.server_now):l.expiryMs||(l.expiryMs=Date.now()+5*60*1e3)}function L(){if(l.done)return;let e=n.querySelector("#pl-qr");e&&(e.innerHTML='<div class="pl-qrerr"><span>QR code expired</span><button class="pl-retry" id="pl-regen">Generate new QR</button></div>');let a=n.querySelector("#pl-regen");a&&(a.onclick=Y);let o=n.querySelector("#pl-timer");o&&(o.textContent="Expired");let p=n.querySelector(".pl-validrow");p&&p.classList.add("pl-expired")}function Y(){if(l.stop){try{l.stop()}catch{}l.stop=null}l.order=null,l.expiryMs=null,M=!1;let e=n.querySelector(".pl-validrow");e&&e.classList.remove("pl-expired");let a=n.querySelector("#pl-qr");a&&(a.innerHTML='<div class="pl-qrloading"></div>'),P(!0)}function H(){!l.order||l.stop||(l.stop=t.watchOrder(l.order.merchant_order_no,e=>{!e||typeof e.status!="number"||(e.status===0?(l.utr=e.utr||l.utr,V()):e.status===3?(clearInterval(l.timer),l.expiryMs=Date.now(),L(),j("failed","QR expired \u2014 generate a new one")):[1,4].includes(e.status)?j("failed","Payment "+(e.status_label||"failed").toLowerCase()):e.status===6&&j("pending","Processing payment\u2026"))}))}function j(e,a){let o=n.querySelector("#pl-status");o&&(o.className=e==="failed"?"pl-pendrow pl-fail":"pl-pendrow",o.innerHTML=(e==="pending"?'<span class="pl-mini-spin"></span> ':"")+f(a))}function V(){l.done||(l.done=!0,clearInterval(l.timer),r("success"),t.onSuccess&&t.onSuccess({merchant_order_no:l.order.merchant_order_no,utr:l.utr,amount:t.amount}),l.utr||Q())}async function Q(){for(let e=0;e<10&&!l.utr;e++){await new Promise(a=>setTimeout(a,4e3));try{let a=await fetch(`${s}/api/order/${l.order.merchant_order_no}`).then(o=>o.json());if(a.utr){l.utr=a.utr;let o=n.querySelector("#pl-pid");o&&l.screen==="success"&&o.insertAdjacentHTML("afterend",`<div class="pl-pid pl-utr">UTR ${f(a.utr)}</div>`);break}}catch{}}}function T(){clearInterval(l.timer);let e=()=>{let a=n.querySelector("#pl-timer");if(!a)return;if(!l.expiryMs){a.textContent="Valid 5:00";return}let o=Math.max(0,Math.round((l.expiryMs-Date.now())/1e3));a.textContent=o>0?"Valid "+le(o):"Expired",o<=0&&(clearInterval(l.timer),L())};e(),l.timer=setInterval(e,1e3)}function C(e){let a=document.getElementById("pl-toast");a||(a=document.createElement("div"),a.id="pl-toast",document.body.appendChild(a)),a.textContent=e,a.classList.add("pl-show"),clearTimeout(a._t),a._t=setTimeout(()=>a.classList.remove("pl-show"),2600)}return r("loader"),setTimeout(()=>{let e=t.prefill||{};e.name&&(e.contact||"").replace(/\D/g,"").length===10?(l.customer={name:e.name,mobile:e.contact.replace(/\D/g,""),email:e.email||""},r("options")):r("contact");let a=n.querySelector("#pl-splash");a&&(a.classList.add("pl-splash-hide"),setTimeout(()=>a.remove(),450))},1600),{close:d}}var A={apiBase:"https://payulink.io/api",assetBase:"https://assetcdn.payulink.io/checkout/v1/assets",name:null,logo:null,brandColor:null,pollMs:2500},q=class t{constructor(s={}){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("PayuLink checkout runs in the browser only. On React Native use @thepayulink/checkout-react-native; on a server use @thepayulink/server.");let i=s.key||s.keyId||s.key_id;if(!i)throw new Error("PayuLink: `key` (your publishable pl_live_\u2026 / pl_test_\u2026 key) is required");if(/^pl_(live|test)_/.test(i)||console.warn("PayuLink: `key` should look like pl_live_\u2026 or pl_test_\u2026"),s.keySecret||s.key_secret)throw new Error("PayuLink: never pass a key_secret to the browser SDK. It belongs on your server only.");this.options=Object.assign({},A,s,{key:i})}open(s={}){let i=Object.assign({},this.options,s),m=String(i.apiBase||"").replace(/\/$/,""),b=String(i.assetBase||`${m}/assets`).replace(/\/$/,""),l=i.order_id||i.orderId;if(!l)throw new Error("PayuLink: `order_id` is required. Create it on your server with POST /v1/orders.");let n=d=>{typeof i.onError=="function"?i.onError(d):console.error("PayuLink:",d.message||d)},y=null,S=null,I=async d=>{var x,k,c;let u=await fetch(`${m}/v1/checkout/session`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key_id:i.key,order_id:l,customer:d?{name:d.name,contact:d.mobile||d.contact,email:d.email}:void 0})}),r=await u.json().catch(()=>({}));if(!u.ok){let _=new Error(((x=r==null?void 0:r.error)==null?void 0:x.description)||`Could not start payment (HTTP ${u.status})`);throw _.code=(k=r==null?void 0:r.error)==null?void 0:k.code,_.retriable=((c=r==null?void 0:r.error)==null?void 0:c.code)==="GATEWAY_BUSY",_}return y=r,{merchant_order_no:r.order_id,amount:r.amount/100,upi_intent_url:r.upi_intent_url,payment_link:r.payment_link,qr_data_url:r.qr_data_url||null,qr_unavailable_reason:r.qr_unavailable_reason||null,qr_retriable:r.qr_retriable===!0,expires_at:r.expires_at?r.expires_at*1e3:null,server_now:Date.now()}},z=(d,u)=>{let r=async()=>{if(y!=null&&y.session_token)try{let c=await(await fetch(`${m}/v1/checkout/session/${encodeURIComponent(y.session_token)}`)).json().catch(()=>({}));c.status==="paid"&&c.payulink_signature&&(S={payulink_order_id:c.payulink_order_id,payulink_payment_id:c.payulink_payment_id,payulink_signature:c.payulink_signature,utr:c.utr||null,amount:c.amount}),u({status:c.status==="paid"?0:c.status==="failed"?1:c.status==="expired"?3:2,status_label:String(c.status||"pending").toUpperCase(),utr:c.utr||null})}catch{}},x=setInterval(r,i.pollMs||A.pollMs);return r(),()=>clearInterval(x)},w={_inner:null,close(){var d;(d=this._inner)==null||d.close()}};return fetch(`${m}/v1/checkout/order/${encodeURIComponent(l)}?key_id=${encodeURIComponent(i.key)}`).then(async d=>{var r;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(((r=u==null?void 0:u.error)==null?void 0:r.description)||"Unknown or expired order");w._inner=R(Object.assign({},{apiBase:m,assetBase:b,name:i.name||u.merchant_name,logo:i.logo||`${b}/payulink-logo.png`,brandColor:i.brandColor,note:i.note,prefill:i.prefill||{},amount:u.amount/100,description:i.description||i.item||u.merchant_name,createOrder:I,watchOrder:z,onSuccess:()=>{let x=S||{payulink_order_id:(y==null?void 0:y.order_id)||l,payulink_payment_id:null,payulink_signature:null};typeof i.handler=="function"&&i.handler(x),typeof i.onSuccess=="function"&&i.onSuccess(x)},onDismiss:()=>{typeof i.onDismiss=="function"&&i.onDismiss()},onError:n}))}).catch(n),w}static open(s={}){return new t(s).open(s)}};typeof window!="undefined"&&(window.PayuLink=q,window.PayulinkCheckout=q);export{q as default};
338
+ <div id="pl-status" class="pl-pendrow"><span class="pl-mini-spin"></span> Waiting for payment\u2026</div>`}function D(e,a){if(e==="contact")a.querySelector("#pl-continue").onclick=()=>{let o=a.querySelector("#pl-name").value.trim(),p=a.querySelector("#pl-mobile").value.replace(/\D/g,""),v=a.querySelector("#pl-email").value.trim(),$=a.querySelector("#pl-cerr");if(o.length<2)return $.textContent="Please enter your name";if(p.length!==10)return $.textContent="Enter a valid 10-digit mobile number";l.customer={name:o,mobile:p,email:v},r("options")};else if(e==="options"){a.querySelectorAll(".pl-navitem").forEach(p=>p.onclick=()=>{p.dataset.m!=="upi"&&C("Coming soon \u2014 please pay via UPI / QR for now")});let o=a.querySelector("#pl-verify");o&&(o.onclick=()=>{let p=(a.querySelector("#pl-vpa").value||"").trim();if(!/^[\w.\-]{2,}@[a-zA-Z]{2,}$/.test(p))return a.querySelector("#pl-vpa").focus(),C("Enter a valid UPI ID, e.g. name@okhdfcbank");let v=l.order&&(l.order.upi_intent_url||l.order.payment_link);v&&/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent)?location.href=v:C("Scan the QR with your phone\u2019s UPI app to complete the payment.")}),T(),P(!0)}}let M=!1;async function P(e){if(e||r("options"),l.order){E();return}if(!M){M=!0;try{l.customer||(l.customer={name:t.prefill.name||"Customer",mobile:(t.prefill.contact||"").replace(/\D/g,""),email:t.prefill.email||""}),l.order=await t.createOrder(l.customer),E(),H()}catch(a){let o=n.querySelector("#pl-qr");if(o){o.innerHTML=`<div class="pl-qrerr"><span>${f(a.message||"Could not start payment")}</span><button class="pl-retry" id="pl-retry">Try again</button></div>`;let p=o.querySelector("#pl-retry");p&&(p.onclick=()=>{M=!1,o.innerHTML='<div class="pl-qrloading"></div>',P(!0)})}}finally{M=!1}}}function E(){let e=l.order;if(!e)return;N(e);let a=n.querySelector("#pl-qr");a&&(e.qr_data_url?a.innerHTML=`<img src="${e.qr_data_url}" alt="UPI QR">`:a.innerHTML=`<div class="pl-qrerr"><span>${f(e.qr_unavailable_reason||"QR unavailable \u2014 use a UPI app below")}</span></div>`);let o=e.upi_intent_url||e.payment_link||"#",p=n.querySelector("#pl-applist");p&&p.querySelectorAll(".pl-uapp").forEach(v=>{v.setAttribute("href",o),v.setAttribute("target","_blank"),v.setAttribute("rel","noopener")}),T()}function N(e){e&&e.expires_at&&e.server_now?l.expiryMs=Date.now()+Math.max(0,e.expires_at-e.server_now):l.expiryMs||(l.expiryMs=Date.now()+5*60*1e3)}function L(){if(l.done)return;let e=n.querySelector("#pl-qr");e&&(e.innerHTML='<div class="pl-qrerr"><span>QR code expired</span><button class="pl-retry" id="pl-regen">Generate new QR</button></div>');let a=n.querySelector("#pl-regen");a&&(a.onclick=Y);let o=n.querySelector("#pl-timer");o&&(o.textContent="Expired");let p=n.querySelector(".pl-validrow");p&&p.classList.add("pl-expired")}function Y(){if(l.stop){try{l.stop()}catch{}l.stop=null}l.order=null,l.expiryMs=null,M=!1;let e=n.querySelector(".pl-validrow");e&&e.classList.remove("pl-expired");let a=n.querySelector("#pl-qr");a&&(a.innerHTML='<div class="pl-qrloading"></div>'),P(!0)}function H(){!l.order||l.stop||(l.stop=t.watchOrder(l.order.merchant_order_no,e=>{!e||typeof e.status!="number"||(e.status===0?(l.utr=e.utr||l.utr,V()):e.status===3?(clearInterval(l.timer),l.expiryMs=Date.now(),L(),j("failed","QR expired \u2014 generate a new one")):[1,4].includes(e.status)?j("failed","Payment "+(e.status_label||"failed").toLowerCase()):e.status===6&&j("pending","Processing payment\u2026"))}))}function j(e,a){let o=n.querySelector("#pl-status");o&&(o.className=e==="failed"?"pl-pendrow pl-fail":"pl-pendrow",o.innerHTML=(e==="pending"?'<span class="pl-mini-spin"></span> ':"")+f(a))}function V(){l.done||(l.done=!0,clearInterval(l.timer),r("success"),t.onSuccess&&t.onSuccess({merchant_order_no:l.order.merchant_order_no,utr:l.utr,amount:t.amount}),l.utr||Q())}async function Q(){for(let e=0;e<10&&!l.utr;e++){await new Promise(a=>setTimeout(a,4e3));try{let a=await fetch(`${s}/api/order/${l.order.merchant_order_no}`).then(o=>o.json());if(a.utr){l.utr=a.utr;let o=n.querySelector("#pl-pid");o&&l.screen==="success"&&o.insertAdjacentHTML("afterend",`<div class="pl-pid pl-utr">UTR ${f(a.utr)}</div>`);break}}catch{}}}function T(){clearInterval(l.timer);let e=()=>{let a=n.querySelector("#pl-timer");if(!a)return;if(!l.expiryMs){a.textContent="Valid 5:00";return}let o=Math.max(0,Math.round((l.expiryMs-Date.now())/1e3));a.textContent=o>0?"Valid "+le(o):"Expired",o<=0&&(clearInterval(l.timer),L())};e(),l.timer=setInterval(e,1e3)}function C(e){let a=document.getElementById("pl-toast");a||(a=document.createElement("div"),a.id="pl-toast",document.body.appendChild(a)),a.textContent=e,a.classList.add("pl-show"),clearTimeout(a._t),a._t=setTimeout(()=>a.classList.remove("pl-show"),2600)}return r("loader"),setTimeout(()=>{let e=t.prefill||{};e.name&&(e.contact||"").replace(/\D/g,"").length===10?(l.customer={name:e.name,mobile:e.contact.replace(/\D/g,""),email:e.email||""},r("options")):r("contact");let a=n.querySelector("#pl-splash");a&&(a.classList.add("pl-splash-hide"),setTimeout(()=>a.remove(),450))},1600),{close:d}}var A={apiBase:"https://payulink.io/api",assetBase:"https://assetcdn.payulink.io/checkout/v1/assets",name:null,logo:null,brandColor:null,pollMs:2500},q=class t{constructor(s={}){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("PayuLink checkout runs in the browser only. On React Native use @thepayulink/checkout-react-native; on a server use @thepayulink/server.");let i=s.key||s.keyId||s.key_id;if(!i)throw new Error("PayuLink: `key` (your publishable pl_live_\u2026 / pl_test_\u2026 key) is required");if(/^pl_(live|test)_/.test(i)||console.warn("PayuLink: `key` should look like pl_live_\u2026 or pl_test_\u2026"),s.keySecret||s.key_secret)throw new Error("PayuLink: never pass a key_secret to the browser SDK. It belongs on your server only.");this.options=Object.assign({},A,s,{key:i})}open(s={}){let i=Object.assign({},this.options,s),m=String(i.apiBase||"").replace(/\/$/,""),b=String(i.assetBase||`${m}/assets`).replace(/\/$/,""),l=i.order_id||i.orderId;if(!l)throw new Error("PayuLink: `order_id` is required. Create it on your server with POST /v1/orders.");let n=d=>{typeof i.onError=="function"?i.onError(d):console.error("PayuLink:",d.message||d)},y=null,S=null,I=async d=>{var x,k,c;let u=await fetch(`${m}/v1/checkout/session`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key_id:i.key,order_id:l,customer:d?{name:d.name,contact:d.mobile||d.contact,email:d.email}:void 0})}),r=await u.json().catch(()=>({}));if(!u.ok){let _=new Error(((x=r==null?void 0:r.error)==null?void 0:x.description)||`Could not start payment (HTTP ${u.status})`);throw _.code=(k=r==null?void 0:r.error)==null?void 0:k.code,_.retriable=((c=r==null?void 0:r.error)==null?void 0:c.code)==="GATEWAY_BUSY",_}return y=r,{merchant_order_no:r.order_id,amount:r.amount/100,upi_intent_url:r.upi_intent_url,payment_link:r.payment_link,qr_data_url:r.qr_data_url||null,qr_unavailable_reason:r.qr_unavailable_reason||null,qr_retriable:r.qr_retriable===!0,expires_at:r.expires_at?r.expires_at*1e3:null,server_now:Date.now()}},z=(d,u)=>{let r=async()=>{if(y!=null&&y.session_token)try{let c=await(await fetch(`${m}/v1/checkout/session/${encodeURIComponent(y.session_token)}`)).json().catch(()=>({}));c.status==="paid"&&c.payulink_signature&&(S={payulink_order_id:c.payulink_order_id,payulink_payment_id:c.payulink_payment_id,payulink_signature:c.payulink_signature,utr:c.utr||null,amount:c.amount}),u({status:c.status==="paid"?0:c.status==="failed"?1:c.status==="expired"?3:2,status_label:String(c.status||"pending").toUpperCase(),utr:c.utr||null})}catch{}},x=setInterval(r,i.pollMs||A.pollMs);return r(),()=>clearInterval(x)},w={_inner:null,close(){var d;(d=this._inner)==null||d.close()}};return fetch(`${m}/v1/checkout/order/${encodeURIComponent(l)}?key_id=${encodeURIComponent(i.key)}`).then(async d=>{var r;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(((r=u==null?void 0:u.error)==null?void 0:r.description)||"Unknown or expired order");w._inner=R(Object.assign({},{apiBase:m,assetBase:b,name:i.name||u.merchant_name,logo:i.logo||`${b}/payulink-logo.png`,brandColor:i.brandColor,note:i.note,prefill:i.prefill||{},amount:u.amount/100,description:i.description||i.item||u.merchant_name,createOrder:I,watchOrder:z,onSuccess:()=>{let x=S||{payulink_order_id:(y==null?void 0:y.order_id)||l,payulink_payment_id:null,payulink_signature:null};typeof i.handler=="function"&&i.handler(x),typeof i.onSuccess=="function"&&i.onSuccess(x)},onDismiss:()=>{typeof i.onDismiss=="function"&&i.onDismiss()},onError:n}))}).catch(n),w}static open(s={}){return new t(s).open(s)}};typeof window!="undefined"&&(window.PayuLink=q,window.PayulinkCheckout=q);export{q as default};
@@ -335,5 +335,5 @@ var PayulinkCheckoutNS=(()=>{var E=Object.defineProperty;var ee=Object.getOwnPro
335
335
  <input class="pl-vpa" id="pl-vpa" placeholder="example@okhdfcbank" autocomplete="off" spellcheck="false">
336
336
  <button class="pl-verify" id="pl-verify">Verify and Pay</button>
337
337
  </div>
338
- <div id="pl-status" class="pl-pendrow"><span class="pl-mini-spin"></span> Waiting for payment\u2026</div>`}function N(e,t){if(e==="contact")t.querySelector("#pl-continue").onclick=()=>{let n=t.querySelector("#pl-name").value.trim(),s=t.querySelector("#pl-mobile").value.replace(/\D/g,""),v=t.querySelector("#pl-email").value.trim(),q=t.querySelector("#pl-cerr");if(n.length<2)return q.textContent="Please enter your name";if(s.length!==10)return q.textContent="Enter a valid 10-digit mobile number";l.customer={name:n,mobile:s,email:v},i("options")};else if(e==="options"){t.querySelectorAll(".pl-navitem").forEach(s=>s.onclick=()=>{s.dataset.m!=="upi"&&C("Coming soon \u2014 please pay via UPI / QR for now")});let n=t.querySelector("#pl-verify");n&&(n.onclick=()=>{let s=(t.querySelector("#pl-vpa").value||"").trim();if(!/^[\w.\-]{2,}@[a-zA-Z]{2,}$/.test(s))return t.querySelector("#pl-vpa").focus(),C("Enter a valid UPI ID, e.g. name@okhdfcbank");let v=l.order&&(l.order.upi_intent_url||l.order.payment_link);v&&/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent)?location.href=v:C("Scan the QR with your phone\u2019s UPI app to complete the payment.")}),B(),P(!0)}}let $=!1;async function P(e){if(e||i("options"),l.order){L();return}if(!$){$=!0;try{l.customer||(l.customer={name:a.prefill.name||"Customer",mobile:(a.prefill.contact||"").replace(/\D/g,""),email:a.prefill.email||""}),l.order=await a.createOrder(l.customer),L(),V()}catch(t){let n=p.querySelector("#pl-qr");if(n){n.innerHTML=`<div class="pl-qrerr"><span>${f(t.message||"Could not start payment")}</span><button class="pl-retry" id="pl-retry">Try again</button></div>`;let s=n.querySelector("#pl-retry");s&&(s.onclick=()=>{$=!1,n.innerHTML='<div class="pl-qrloading"></div>',P(!0)})}}finally{$=!1}}}function L(){let e=l.order;if(!e)return;Y(e);let t=p.querySelector("#pl-qr");t&&(e.qr_data_url?t.innerHTML=`<img src="${e.qr_data_url}" alt="UPI QR">`:t.innerHTML='<div class="pl-qrerr"><span>QR unavailable \u2014 use a UPI app below</span></div>');let n=e.upi_intent_url||e.payment_link||"#",s=p.querySelector("#pl-applist");s&&s.querySelectorAll(".pl-uapp").forEach(v=>{v.setAttribute("href",n),v.setAttribute("target","_blank"),v.setAttribute("rel","noopener")}),B()}function Y(e){e&&e.expires_at&&e.server_now?l.expiryMs=Date.now()+Math.max(0,e.expires_at-e.server_now):l.expiryMs||(l.expiryMs=Date.now()+5*60*1e3)}function T(){if(l.done)return;let e=p.querySelector("#pl-qr");e&&(e.innerHTML='<div class="pl-qrerr"><span>QR code expired</span><button class="pl-retry" id="pl-regen">Generate new QR</button></div>');let t=p.querySelector("#pl-regen");t&&(t.onclick=H);let n=p.querySelector("#pl-timer");n&&(n.textContent="Expired");let s=p.querySelector(".pl-validrow");s&&s.classList.add("pl-expired")}function H(){if(l.stop){try{l.stop()}catch{}l.stop=null}l.order=null,l.expiryMs=null,$=!1;let e=p.querySelector(".pl-validrow");e&&e.classList.remove("pl-expired");let t=p.querySelector("#pl-qr");t&&(t.innerHTML='<div class="pl-qrloading"></div>'),P(!0)}function V(){!l.order||l.stop||(l.stop=a.watchOrder(l.order.merchant_order_no,e=>{!e||typeof e.status!="number"||(e.status===0?(l.utr=e.utr||l.utr,Q()):e.status===3?(clearInterval(l.timer),l.expiryMs=Date.now(),T(),j("failed","QR expired \u2014 generate a new one")):[1,4].includes(e.status)?j("failed","Payment "+(e.status_label||"failed").toLowerCase()):e.status===6&&j("pending","Processing payment\u2026"))}))}function j(e,t){let n=p.querySelector("#pl-status");n&&(n.className=e==="failed"?"pl-pendrow pl-fail":"pl-pendrow",n.innerHTML=(e==="pending"?'<span class="pl-mini-spin"></span> ':"")+f(t))}function Q(){l.done||(l.done=!0,clearInterval(l.timer),i("success"),a.onSuccess&&a.onSuccess({merchant_order_no:l.order.merchant_order_no,utr:l.utr,amount:a.amount}),l.utr||X())}async function X(){for(let e=0;e<10&&!l.utr;e++){await new Promise(t=>setTimeout(t,4e3));try{let t=await fetch(`${o}/api/order/${l.order.merchant_order_no}`).then(n=>n.json());if(t.utr){l.utr=t.utr;let n=p.querySelector("#pl-pid");n&&l.screen==="success"&&n.insertAdjacentHTML("afterend",`<div class="pl-pid pl-utr">UTR ${f(t.utr)}</div>`);break}}catch{}}}function B(){clearInterval(l.timer);let e=()=>{let t=p.querySelector("#pl-timer");if(!t)return;if(!l.expiryMs){t.textContent="Valid 5:00";return}let n=Math.max(0,Math.round((l.expiryMs-Date.now())/1e3));t.textContent=n>0?"Valid "+pe(n):"Expired",n<=0&&(clearInterval(l.timer),T())};e(),l.timer=setInterval(e,1e3)}function C(e){let t=document.getElementById("pl-toast");t||(t=document.createElement("div"),t.id="pl-toast",document.body.appendChild(t)),t.textContent=e,t.classList.add("pl-show"),clearTimeout(t._t),t._t=setTimeout(()=>t.classList.remove("pl-show"),2600)}return i("loader"),setTimeout(()=>{let e=a.prefill||{};e.name&&(e.contact||"").replace(/\D/g,"").length===10?(l.customer={name:e.name,mobile:e.contact.replace(/\D/g,""),email:e.email||""},i("options")):i("contact");let t=p.querySelector("#pl-splash");t&&(t.classList.add("pl-splash-hide"),setTimeout(()=>t.remove(),450))},1600),{close:d}}var D={apiBase:"https://payulink.io/api",assetBase:"https://assetcdn.payulink.io/checkout/v1/assets",name:null,logo:null,brandColor:null,pollMs:2500},w=class a{constructor(o={}){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("PayuLink checkout runs in the browser only. On React Native use @thepayulink/checkout-react-native; on a server use @thepayulink/server.");let r=o.key||o.keyId||o.key_id;if(!r)throw new Error("PayuLink: `key` (your publishable pl_live_\u2026 / pl_test_\u2026 key) is required");if(/^pl_(live|test)_/.test(r)||console.warn("PayuLink: `key` should look like pl_live_\u2026 or pl_test_\u2026"),o.keySecret||o.key_secret)throw new Error("PayuLink: never pass a key_secret to the browser SDK. It belongs on your server only.");this.options=Object.assign({},D,o,{key:r})}open(o={}){let r=Object.assign({},this.options,o),y=String(r.apiBase||"").replace(/\/$/,""),h=String(r.assetBase||`${y}/assets`).replace(/\/$/,""),l=r.order_id||r.orderId;if(!l)throw new Error("PayuLink: `order_id` is required. Create it on your server with POST /v1/orders.");let p=d=>{typeof r.onError=="function"?r.onError(d):console.error("PayuLink:",d.message||d)},x=null,S=null,I=async d=>{var g,_,c;let u=await fetch(`${y}/v1/checkout/session`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key_id:r.key,order_id:l,customer:d?{name:d.name,contact:d.mobile||d.contact,email:d.email}:void 0})}),i=await u.json().catch(()=>({}));if(!u.ok){let M=new Error(((g=i==null?void 0:i.error)==null?void 0:g.description)||`Could not start payment (HTTP ${u.status})`);throw M.code=(_=i==null?void 0:i.error)==null?void 0:_.code,M.retriable=((c=i==null?void 0:i.error)==null?void 0:c.code)==="GATEWAY_BUSY",M}return x=i,{merchant_order_no:i.order_id,amount:i.amount/100,upi_intent_url:i.upi_intent_url,payment_link:i.payment_link,qr_data_url:i.qr_data_url||null,qr_unavailable_reason:i.qr_unavailable_reason||null,qr_retriable:i.qr_retriable===!0,expires_at:i.expires_at?i.expires_at*1e3:null,server_now:Date.now()}},z=(d,u)=>{let i=async()=>{if(x!=null&&x.session_token)try{let c=await(await fetch(`${y}/v1/checkout/session/${encodeURIComponent(x.session_token)}`)).json().catch(()=>({}));c.status==="paid"&&c.payulink_signature&&(S={payulink_order_id:c.payulink_order_id,payulink_payment_id:c.payulink_payment_id,payulink_signature:c.payulink_signature,utr:c.utr||null,amount:c.amount}),u({status:c.status==="paid"?0:c.status==="failed"?1:c.status==="expired"?3:2,status_label:String(c.status||"pending").toUpperCase(),utr:c.utr||null})}catch{}},g=setInterval(i,r.pollMs||D.pollMs);return i(),()=>clearInterval(g)},k={_inner:null,close(){var d;(d=this._inner)==null||d.close()}};return fetch(`${y}/v1/checkout/order/${encodeURIComponent(l)}?key_id=${encodeURIComponent(r.key)}`).then(async d=>{var i;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(((i=u==null?void 0:u.error)==null?void 0:i.description)||"Unknown or expired order");k._inner=A(Object.assign({},{apiBase:y,assetBase:h,name:r.name||u.merchant_name,logo:r.logo||`${h}/payulink-logo.png`,brandColor:r.brandColor,note:r.note,prefill:r.prefill||{},amount:u.amount/100,description:r.description||r.item||u.merchant_name,createOrder:I,watchOrder:z,onSuccess:()=>{let g=S||{payulink_order_id:(x==null?void 0:x.order_id)||l,payulink_payment_id:null,payulink_signature:null};typeof r.handler=="function"&&r.handler(g),typeof r.onSuccess=="function"&&r.onSuccess(g)},onDismiss:()=>{typeof r.onDismiss=="function"&&r.onDismiss()},onError:p}))}).catch(p),k}static open(o={}){return new a(o).open(o)}};typeof window!="undefined"&&(window.PayuLink=w,window.PayulinkCheckout=w);return ie(de);})();
338
+ <div id="pl-status" class="pl-pendrow"><span class="pl-mini-spin"></span> Waiting for payment\u2026</div>`}function N(e,t){if(e==="contact")t.querySelector("#pl-continue").onclick=()=>{let n=t.querySelector("#pl-name").value.trim(),s=t.querySelector("#pl-mobile").value.replace(/\D/g,""),v=t.querySelector("#pl-email").value.trim(),q=t.querySelector("#pl-cerr");if(n.length<2)return q.textContent="Please enter your name";if(s.length!==10)return q.textContent="Enter a valid 10-digit mobile number";l.customer={name:n,mobile:s,email:v},i("options")};else if(e==="options"){t.querySelectorAll(".pl-navitem").forEach(s=>s.onclick=()=>{s.dataset.m!=="upi"&&C("Coming soon \u2014 please pay via UPI / QR for now")});let n=t.querySelector("#pl-verify");n&&(n.onclick=()=>{let s=(t.querySelector("#pl-vpa").value||"").trim();if(!/^[\w.\-]{2,}@[a-zA-Z]{2,}$/.test(s))return t.querySelector("#pl-vpa").focus(),C("Enter a valid UPI ID, e.g. name@okhdfcbank");let v=l.order&&(l.order.upi_intent_url||l.order.payment_link);v&&/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent)?location.href=v:C("Scan the QR with your phone\u2019s UPI app to complete the payment.")}),B(),P(!0)}}let $=!1;async function P(e){if(e||i("options"),l.order){L();return}if(!$){$=!0;try{l.customer||(l.customer={name:a.prefill.name||"Customer",mobile:(a.prefill.contact||"").replace(/\D/g,""),email:a.prefill.email||""}),l.order=await a.createOrder(l.customer),L(),V()}catch(t){let n=p.querySelector("#pl-qr");if(n){n.innerHTML=`<div class="pl-qrerr"><span>${f(t.message||"Could not start payment")}</span><button class="pl-retry" id="pl-retry">Try again</button></div>`;let s=n.querySelector("#pl-retry");s&&(s.onclick=()=>{$=!1,n.innerHTML='<div class="pl-qrloading"></div>',P(!0)})}}finally{$=!1}}}function L(){let e=l.order;if(!e)return;Y(e);let t=p.querySelector("#pl-qr");t&&(e.qr_data_url?t.innerHTML=`<img src="${e.qr_data_url}" alt="UPI QR">`:t.innerHTML=`<div class="pl-qrerr"><span>${f(e.qr_unavailable_reason||"QR unavailable \u2014 use a UPI app below")}</span></div>`);let n=e.upi_intent_url||e.payment_link||"#",s=p.querySelector("#pl-applist");s&&s.querySelectorAll(".pl-uapp").forEach(v=>{v.setAttribute("href",n),v.setAttribute("target","_blank"),v.setAttribute("rel","noopener")}),B()}function Y(e){e&&e.expires_at&&e.server_now?l.expiryMs=Date.now()+Math.max(0,e.expires_at-e.server_now):l.expiryMs||(l.expiryMs=Date.now()+5*60*1e3)}function T(){if(l.done)return;let e=p.querySelector("#pl-qr");e&&(e.innerHTML='<div class="pl-qrerr"><span>QR code expired</span><button class="pl-retry" id="pl-regen">Generate new QR</button></div>');let t=p.querySelector("#pl-regen");t&&(t.onclick=H);let n=p.querySelector("#pl-timer");n&&(n.textContent="Expired");let s=p.querySelector(".pl-validrow");s&&s.classList.add("pl-expired")}function H(){if(l.stop){try{l.stop()}catch{}l.stop=null}l.order=null,l.expiryMs=null,$=!1;let e=p.querySelector(".pl-validrow");e&&e.classList.remove("pl-expired");let t=p.querySelector("#pl-qr");t&&(t.innerHTML='<div class="pl-qrloading"></div>'),P(!0)}function V(){!l.order||l.stop||(l.stop=a.watchOrder(l.order.merchant_order_no,e=>{!e||typeof e.status!="number"||(e.status===0?(l.utr=e.utr||l.utr,Q()):e.status===3?(clearInterval(l.timer),l.expiryMs=Date.now(),T(),j("failed","QR expired \u2014 generate a new one")):[1,4].includes(e.status)?j("failed","Payment "+(e.status_label||"failed").toLowerCase()):e.status===6&&j("pending","Processing payment\u2026"))}))}function j(e,t){let n=p.querySelector("#pl-status");n&&(n.className=e==="failed"?"pl-pendrow pl-fail":"pl-pendrow",n.innerHTML=(e==="pending"?'<span class="pl-mini-spin"></span> ':"")+f(t))}function Q(){l.done||(l.done=!0,clearInterval(l.timer),i("success"),a.onSuccess&&a.onSuccess({merchant_order_no:l.order.merchant_order_no,utr:l.utr,amount:a.amount}),l.utr||X())}async function X(){for(let e=0;e<10&&!l.utr;e++){await new Promise(t=>setTimeout(t,4e3));try{let t=await fetch(`${o}/api/order/${l.order.merchant_order_no}`).then(n=>n.json());if(t.utr){l.utr=t.utr;let n=p.querySelector("#pl-pid");n&&l.screen==="success"&&n.insertAdjacentHTML("afterend",`<div class="pl-pid pl-utr">UTR ${f(t.utr)}</div>`);break}}catch{}}}function B(){clearInterval(l.timer);let e=()=>{let t=p.querySelector("#pl-timer");if(!t)return;if(!l.expiryMs){t.textContent="Valid 5:00";return}let n=Math.max(0,Math.round((l.expiryMs-Date.now())/1e3));t.textContent=n>0?"Valid "+pe(n):"Expired",n<=0&&(clearInterval(l.timer),T())};e(),l.timer=setInterval(e,1e3)}function C(e){let t=document.getElementById("pl-toast");t||(t=document.createElement("div"),t.id="pl-toast",document.body.appendChild(t)),t.textContent=e,t.classList.add("pl-show"),clearTimeout(t._t),t._t=setTimeout(()=>t.classList.remove("pl-show"),2600)}return i("loader"),setTimeout(()=>{let e=a.prefill||{};e.name&&(e.contact||"").replace(/\D/g,"").length===10?(l.customer={name:e.name,mobile:e.contact.replace(/\D/g,""),email:e.email||""},i("options")):i("contact");let t=p.querySelector("#pl-splash");t&&(t.classList.add("pl-splash-hide"),setTimeout(()=>t.remove(),450))},1600),{close:d}}var D={apiBase:"https://payulink.io/api",assetBase:"https://assetcdn.payulink.io/checkout/v1/assets",name:null,logo:null,brandColor:null,pollMs:2500},w=class a{constructor(o={}){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("PayuLink checkout runs in the browser only. On React Native use @thepayulink/checkout-react-native; on a server use @thepayulink/server.");let r=o.key||o.keyId||o.key_id;if(!r)throw new Error("PayuLink: `key` (your publishable pl_live_\u2026 / pl_test_\u2026 key) is required");if(/^pl_(live|test)_/.test(r)||console.warn("PayuLink: `key` should look like pl_live_\u2026 or pl_test_\u2026"),o.keySecret||o.key_secret)throw new Error("PayuLink: never pass a key_secret to the browser SDK. It belongs on your server only.");this.options=Object.assign({},D,o,{key:r})}open(o={}){let r=Object.assign({},this.options,o),y=String(r.apiBase||"").replace(/\/$/,""),h=String(r.assetBase||`${y}/assets`).replace(/\/$/,""),l=r.order_id||r.orderId;if(!l)throw new Error("PayuLink: `order_id` is required. Create it on your server with POST /v1/orders.");let p=d=>{typeof r.onError=="function"?r.onError(d):console.error("PayuLink:",d.message||d)},x=null,S=null,I=async d=>{var g,_,c;let u=await fetch(`${y}/v1/checkout/session`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key_id:r.key,order_id:l,customer:d?{name:d.name,contact:d.mobile||d.contact,email:d.email}:void 0})}),i=await u.json().catch(()=>({}));if(!u.ok){let M=new Error(((g=i==null?void 0:i.error)==null?void 0:g.description)||`Could not start payment (HTTP ${u.status})`);throw M.code=(_=i==null?void 0:i.error)==null?void 0:_.code,M.retriable=((c=i==null?void 0:i.error)==null?void 0:c.code)==="GATEWAY_BUSY",M}return x=i,{merchant_order_no:i.order_id,amount:i.amount/100,upi_intent_url:i.upi_intent_url,payment_link:i.payment_link,qr_data_url:i.qr_data_url||null,qr_unavailable_reason:i.qr_unavailable_reason||null,qr_retriable:i.qr_retriable===!0,expires_at:i.expires_at?i.expires_at*1e3:null,server_now:Date.now()}},z=(d,u)=>{let i=async()=>{if(x!=null&&x.session_token)try{let c=await(await fetch(`${y}/v1/checkout/session/${encodeURIComponent(x.session_token)}`)).json().catch(()=>({}));c.status==="paid"&&c.payulink_signature&&(S={payulink_order_id:c.payulink_order_id,payulink_payment_id:c.payulink_payment_id,payulink_signature:c.payulink_signature,utr:c.utr||null,amount:c.amount}),u({status:c.status==="paid"?0:c.status==="failed"?1:c.status==="expired"?3:2,status_label:String(c.status||"pending").toUpperCase(),utr:c.utr||null})}catch{}},g=setInterval(i,r.pollMs||D.pollMs);return i(),()=>clearInterval(g)},k={_inner:null,close(){var d;(d=this._inner)==null||d.close()}};return fetch(`${y}/v1/checkout/order/${encodeURIComponent(l)}?key_id=${encodeURIComponent(r.key)}`).then(async d=>{var i;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(((i=u==null?void 0:u.error)==null?void 0:i.description)||"Unknown or expired order");k._inner=A(Object.assign({},{apiBase:y,assetBase:h,name:r.name||u.merchant_name,logo:r.logo||`${h}/payulink-logo.png`,brandColor:r.brandColor,note:r.note,prefill:r.prefill||{},amount:u.amount/100,description:r.description||r.item||u.merchant_name,createOrder:I,watchOrder:z,onSuccess:()=>{let g=S||{payulink_order_id:(x==null?void 0:x.order_id)||l,payulink_payment_id:null,payulink_signature:null};typeof r.handler=="function"&&r.handler(g),typeof r.onSuccess=="function"&&r.onSuccess(g)},onDismiss:()=>{typeof r.onDismiss=="function"&&r.onDismiss()},onError:p}))}).catch(p),k}static open(o={}){return new a(o).open(o)}};typeof window!="undefined"&&(window.PayuLink=w,window.PayulinkCheckout=w);return ie(de);})();
339
339
  window.PayulinkCheckout=PayulinkCheckoutNS.default||PayulinkCheckoutNS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thepayulink/checkout",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "PayuLink Checkout — open a server-created order in the browser with your publishable key.",
5
5
  "type": "module",
6
6
  "main": "./dist/payulink-checkout.cjs",
package/src/modal.js CHANGED
@@ -263,7 +263,11 @@ export function openModal(o) {
263
263
  const q = root.querySelector('#pl-qr');
264
264
  if (q) {
265
265
  if (ord.qr_data_url) q.innerHTML = `<img src="${ord.qr_data_url}" alt="UPI QR">`;
266
- else q.innerHTML = `<div class="pl-qrerr"><span>QR unavailable use a UPI app below</span></div>`;
266
+ // Say WHY there's no QR. "QR unavailable" covered two unrelated causes
267
+ // (provider timeout vs no liquidity) and told the customer nothing actionable.
268
+ // The order is still payable via the UPI-app button below.
269
+ else q.innerHTML = `<div class="pl-qrerr"><span>${esc(ord.qr_unavailable_reason
270
+ || 'QR unavailable — use a UPI app below')}</span></div>`;
267
271
  }
268
272
  const intent = ord.upi_intent_url || ord.payment_link || '#';
269
273
  const list = root.querySelector('#pl-applist');