@dropp.cc/payment-sdk 1.0.5 โ†’ 1.0.7

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 CHANGED
@@ -88,11 +88,11 @@ Dropp.pay({
88
88
  });
89
89
  ```
90
90
 
91
- ## Hosted Pages
91
+ ## Pages
92
92
 
93
93
  The Web SDK can also open Dropp-hosted pages inside the same modal container.
94
94
 
95
- ### `Dropp.openDashboard(options)`
95
+ ### `Dropp.dashboard(options)`
96
96
 
97
97
  Loads `/#/firsttimeflow` for the dashboard/home page.
98
98
 
@@ -100,11 +100,11 @@ Loads `/#/firsttimeflow` for the dashboard/home page.
100
100
 
101
101
  Loads `/#/unlink` for the account unlink page.
102
102
 
103
- ### `Dropp.loadTransactions(options)`
103
+ ### `Dropp.transactions(options)`
104
104
 
105
105
  Loads `/#/transactions` for the transactions page.
106
106
 
107
- ### `Dropp.loadOffers(options)`
107
+ ### `Dropp.offers(options)`
108
108
 
109
109
  Loads `/#/offers` for the offers page.
110
110
 
@@ -116,15 +116,15 @@ Loads `/#/offers` for the offers page.
116
116
  ### Hosted Page Example:
117
117
 
118
118
  ```javascript
119
- await Dropp.openDashboard({
119
+ await Dropp.dashboard({
120
120
  onClose: () => {
121
121
  console.log('Dashboard modal closed');
122
122
  }
123
123
  });
124
124
 
125
125
  await Dropp.unlinkAccount();
126
- await Dropp.loadTransactions();
127
- await Dropp.loadOffers();
126
+ await Dropp.transactions();
127
+ await Dropp.offers();
128
128
  ```
129
129
 
130
130
  ### SDK Instance Example:
@@ -137,10 +137,10 @@ const { sdk } = await Dropp.init({
137
137
  environment: 'production'
138
138
  });
139
139
 
140
- await sdk.openDashboard();
140
+ await sdk.dashboard();
141
141
  await sdk.unlinkAccount();
142
- await sdk.loadTransactions();
143
- await sdk.loadOffers();
142
+ await sdk.transactions();
143
+ await sdk.offers();
144
144
  ```
145
145
 
146
146
  ## Environments
@@ -402,3 +402,14 @@ MIT License - see LICENSE file for details
402
402
  - Secure postMessage communication
403
403
  - Framework-agnostic design
404
404
  - Full TypeScript definitions
405
+
406
+ ### v1.0.3 (2026-07-06)
407
+ - Added Support for the Home/Dashboard.
408
+
409
+ ### v1.0.4 (2026-07-07)
410
+ - Added Support for the Unlink account.
411
+
412
+ ### v1.0.5 (2026-07-09)
413
+ - Added Support for the Transactions.
414
+ - Added Support for the Offers.
415
+ - Added Support for Security before open any customized method.
@@ -1,2 +1,2 @@
1
- const e={READY:"DROPP_SDK_READY",PAYMENT_SUCCESS:"PAYMENT_SUCCESS",PAYMENT_FAILED:"PAYMENT_FAILED",PAYMENT_CANCELLED:"PAYMENT_CANCELLED",CLOSE_WEBVIEW:"CLOSE_WEBVIEW",AUTO_CLOSE_WEBVIEW:"AUTO_CLOSE_WEBVIEW",PAYMENT_PAGE_LOADED:"PAYMENT_PAGE_LOADED"},t="DROPP_SDK_INIT",n="DROPP_SDK_CLOSE",i={PRODUCTION:"production",QA:"qa",SANDBOX:"sandbox"},s={[i.PRODUCTION]:"https://wv.dropp.cc",[i.QA]:"https://wv.qa.dropp.cc",[i.SANDBOX]:"https://wv.sandbox.dropp.cc"},o={[i.PRODUCTION]:["https://wv.dropp.cc"],[i.QA]:["https://wv.qa.dropp.cc"],[i.SANDBOX]:["https://wv.sandbox.dropp.cc"]},r=3e4,a=6e5,l={STANDARD:"standard",PREAUTH:"preauth",RECURRING:"recurring"},c="INIT_TIMEOUT",d="PAYMENT_TIMEOUT",p="INVALID_CONFIG",h="ALREADY_OPEN",u="UNKNOWN_ERROR",m="1.0.2";const g=new class{constructor(e,t={}){this.environment=e,this.forceEnabled=!!t.enabled,this.enabled=this._shouldEnableLogging()}_shouldEnableLogging(){return this.forceEnabled}setEnvironment(e,t={}){this.environment=e,"boolean"==typeof t.enabled&&(this.forceEnabled=t.enabled),this.enabled=this._shouldEnableLogging()}setEnabled(e){this.forceEnabled=!!e,this.enabled=this._shouldEnableLogging()}log(...e){this.enabled&&console.log(...e)}warn(...e){this.enabled&&console.warn(...e)}error(...e){this.enabled&&console.error(...e)}debug(...e){this.enabled&&console.debug(...e)}info(...e){this.enabled&&console.info(...e)}}("qa",{enabled:!1}),y=["USD","HBAR","USDC"],f=["NONE","HALF_HOURLY","HOURLY","DAILY","WEEKLY","MONTHLY","YEARLY"],D=[l.STANDARD,l.PREAUTH,l.RECURRING];function S(e,t={}){const{isProduction:n=!1,allowLocalCallbacksInNonProd:i=!1}=t;if("string"!=typeof e||!e.trim())return!1;try{const t=new URL(e.trim()),s="https:"===t.protocol;if(!("http:"===t.protocol)&&!s)return!1;return function(e){if(!e)return!1;const t=e.trim().toLowerCase();if("localhost"===t||"127.0.0.1"===t||"::1"===t||t.endsWith(".local"))return!0;if(!/^(\d{1,3}\.){3}\d{1,3}$/.test(t))return!1;const n=t.split(".").map(e=>Number(e));if(n.some(e=>Number.isNaN(e)||e<0||e>255))return!1;const[i,s]=n;return 10===i||127===i||172===i&&s>=16&&s<=31||192===i&&168===s||169===i&&254===s}(t.hostname)?!n&&i:!n||s}catch{return!1}}function v(e={},t={}){const n=[],i=e.paymentType||l.STANDARD,s="production"===(t.environment||"").toLowerCase(),o=!!t.allowLocalCallbacksInNonProd,r="string"==typeof e.currency?e.currency.trim().toUpperCase():"";if(D.includes(i)||n.push(`paymentType must be one of: ${D.join(", ")}`),void 0===e.amount||null===e.amount||""===e.amount?n.push("amount is required"):function(e){const t="number"==typeof e?e:parseFloat(e);return"number"==typeof t&&!Number.isNaN(t)&&t>0}(e.amount)||n.push("amount must be a positive number"),e.currency&&"string"==typeof e.currency&&e.currency.trim()?y.includes(r)||n.push(`currency must be one of: ${y.join(", ")}`):n.push("currency is required"),e.itemName&&"string"==typeof e.itemName&&e.itemName.trim()||n.push("itemName is required"),i===l.PREAUTH&&(r&&"USD"!==r&&n.push("currency must be USD for preauth payments"),e.callbackUrl&&String(e.callbackUrl).trim()?S(e.callbackUrl,{isProduction:s,allowLocalCallbacksInNonProd:o})||n.push(s?"callbackUrl must be HTTPS in production and cannot target loopback/private hosts":"callbackUrl must be a valid HTTP/HTTPS URL and cannot target loopback/private hosts unless explicitly enabled"):n.push("callbackUrl (signing URL) is required for preauth payments"),void 0===e.authHoldTimeInSeconds||null===e.authHoldTimeInSeconds||""===e.authHoldTimeInSeconds?n.push("authHoldTimeInSeconds is required for preauth payments"):function(e){const t="number"==typeof e?e:parseInt(e,10);return Number.isInteger(t)&&t>0}(e.authHoldTimeInSeconds)||n.push("authHoldTimeInSeconds must be a positive integer (seconds)")),i===l.RECURRING){e.callbackUrl&&String(e.callbackUrl).trim()?S(e.callbackUrl,{isProduction:s,allowLocalCallbacksInNonProd:o})||n.push(s?"callbackUrl must be HTTPS in production and cannot target loopback/private hosts":"callbackUrl must be a valid HTTP/HTTPS URL and cannot target loopback/private hosts unless explicitly enabled"):n.push("callbackUrl (signing URL) is required for recurring payments");const t=(e.frequency||e.recurringInterval||"").toString().trim().toUpperCase();t?f.includes(t)||n.push(`frequency must be one of: ${f.join(", ")}`):n.push("frequency is required for recurring payments"),e.recurringEndDate&&String(e.recurringEndDate).trim()?!function(e){if("string"!=typeof e||!e.trim())return!1;const t=new Date(e.trim());return!Number.isNaN(t.getTime())}(e.recurringEndDate)?n.push("recurringEndDate must be a valid ISO date-time string"):new Date(e.recurringEndDate.trim())<=new Date&&n.push("recurringEndDate must be in the future"):n.push("recurringEndDate (expiry) is required for recurring payments")}return{valid:0===n.length,errors:n}}function b(e,t,n={}){return{code:e,message:t,details:n,timestamp:(new Date).toISOString(),toString(){return this.message||"Dropp SDK error"}}}class w{constructor(e,t,n=null){this.environment=e,this.onMessage=t,this.sessionId=`dropp-sdk-${Date.now()}-${Math.random().toString(36).substring(2,15)}`,g.log("[MessageHandler] Session initialized"),this.iframe=null,this.allowedOrigins=n?.length>0?n:o[e]||[],this.messageListener=null,this.pendingMessages=new Map}init(e){this.iframe=e,this.messageListener=this._handleMessage.bind(this),window.addEventListener("message",this.messageListener)}destroy(){this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.iframe=null,this.pendingMessages.clear()}_handleMessage(e){if(g.log("[MessageHandler] Received postMessage event"),e.source===window)return void g.log("[MessageHandler] Ignoring message from self");if(!this._validateOrigin(e.origin))return void g.warn("[Dropp SDK] Rejected message from untrusted origin:",e.origin);if(!this.iframe||e.source!==this.iframe.contentWindow)return void g.warn("[Dropp SDK] Rejected message from unexpected source",{eventOrigin:e.origin});const t=e.data;this._validateMessageStructure(t)?t.sessionId&&t.sessionId!==this.sessionId?g.warn("[Dropp SDK] Rejected message with invalid session ID"):(g.log("[MessageHandler] Message passed validation"),this._processMessage(t)):g.warn("[Dropp SDK] Rejected message with invalid structure")}_validateOrigin(e){return!(!e.startsWith("http://localhost:")&&!e.startsWith("http://127.0.0.1:"))||this.allowedOrigins.includes(e)}_validateMessageStructure(t){if(!t||"object"!=typeof t)return!1;if(!t.type||"string"!=typeof t.type)return!1;return!!Object.values(e).includes(t.type)&&!!t.timestamp}_processMessage(e){g.log("[Dropp SDK] Received message:",e.type),this.onMessage&&this.onMessage(e)}sendToPaymentApp(e,t={}){if(!this.iframe||!this.iframe.contentWindow)return g.error("[Dropp SDK] Cannot send message: iframe not ready"),!1;const n={type:e,data:t,sessionId:this.sessionId,timestamp:(new Date).toISOString(),sdkVersion:"1.0.0"},i=this.allowedOrigins[0]||"*";try{return this.iframe.contentWindow.postMessage(n,i),g.log("[Dropp SDK] Sent message:",e),!0}catch(e){return g.error("[Dropp SDK] Error sending message:",e),!1}}sendInit(e){return this.sendToPaymentApp(t,{mode:"sdk",config:e})}sendClose(){return this.sendToPaymentApp(n,{})}getSessionId(){return this.sessionId}}class T{constructor(e){this.onClose=e,this.overlay=null,this.container=null,this.iframe=null,this.closeButton=null,this.isOpen=!1,this.escapeListener=null}open(){return this.isOpen?(g.warn("[Dropp SDK] Modal is already open"),null):(this._createModal(),this._attachEventListeners(),this._show(),this.isOpen=!0,this.iframe)}close(){g.log("[ModalManager] ๐Ÿšฆ close() called, isOpen:",this.isOpen),this.isOpen?(g.log("[ModalManager] ๐Ÿšฆ Hiding modal..."),this._hide(),g.log("[ModalManager] ๐Ÿšฆ Removing event listeners..."),this._removeEventListeners(),g.log("[ModalManager] ๐Ÿšฆ Destroying modal..."),this._destroyModal(),this.isOpen=!1,g.log("[ModalManager] โœ… Modal close sequence initiated")):g.log("[ModalManager] โš ๏ธ Modal is not open, skipping close")}_createModal(){this.overlay=document.createElement("div"),this.overlay.id="dropp-payment-overlay",this._applyOverlayStyles(this.overlay),this.container=document.createElement("div"),this.container.id="dropp-payment-container",this._applyContainerStyles(this.container),this.iframe=document.createElement("iframe"),this.iframe.id="dropp-payment-iframe",this.iframe.setAttribute("allow","payment"),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),this.iframe.setAttribute("referrerpolicy","no-referrer"),this.iframe.setAttribute("title","Dropp Payment"),this._applyIframeStyles(this.iframe),this.container.appendChild(this.iframe),this.overlay.appendChild(this.container),document.body.appendChild(this.overlay)}_applyOverlayStyles(e){Object.assign(e.style,{position:"fixed",inset:"0",width:"100vw",height:"100vh",margin:"0",padding:"20px",boxSizing:"border-box",backgroundColor:"rgba(0, 0, 0, 0.6)",zIndex:999999..toString(),display:"flex",alignItems:"center",justifyContent:"center",opacity:"0",transition:"opacity 0.3s ease",backdropFilter:"blur(4px)",overflow:"auto"})}_applyContainerStyles(e){const t=window.innerWidth<768;this._isMobile=t,Object.assign(e.style,{position:"relative",flex:"0 0 auto",alignSelf:"center",margin:"auto",width:"100%",maxWidth:t?"100%":"400px",height:t?"100%":"auto",minHeight:t?"100%":"800px",maxHeight:t?"100%":"min(1000px, calc(100vh - 40px))",backgroundColor:"#ffffff",borderRadius:t?"0":"16px",boxShadow:"0 20px 60px rgba(0, 0, 0, 0.3)",overflow:"hidden",transform:"scale(0.95)",transition:"transform 0.3s ease, opacity 0.3s ease",display:"flex",flexDirection:"column"})}_getContainerTransform(e){return`scale(${e})`}_applyCloseButtonStyles(e){Object.assign(e.style,{position:"absolute",top:"16px",right:"16px",zIndex:"10",width:"40px",height:"40px",border:"none",borderRadius:"50%",backgroundColor:"rgba(255, 255, 255, 0.9)",color:"#333",fontSize:"28px",lineHeight:"1",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.15)",transition:"all 0.2s ease",fontFamily:"Arial, sans-serif",padding:"0"}),e.addEventListener("mouseenter",()=>{Object.assign(e.style,{backgroundColor:"#f5f5f5",transform:"scale(1.1)"})}),e.addEventListener("mouseleave",()=>{Object.assign(e.style,{backgroundColor:"rgba(255, 255, 255, 0.9)",transform:"scale(1)"})})}_applyIframeStyles(e){const t=this._isMobile;Object.assign(e.style,{width:"100%",flex:"1 1 auto",minHeight:t?"100%":"min(520px, calc(90vh - 40px))",height:t?"100%":"min(520px, calc(90vh - 40px))",border:"none",display:"block"})}_show(){document.body.style.overflow="hidden",requestAnimationFrame(()=>{this.overlay&&(this.overlay.style.opacity="1"),this.container&&(this.container.style.transform=this._getContainerTransform(1))})}_hide(){g.log("[ModalManager] ๐ŸŽญ _hide() called"),this.overlay&&(this.overlay.style.opacity="0",g.log("[ModalManager] ๐ŸŽญ Overlay opacity set to 0")),this.container&&(this.container.style.transform=this._getContainerTransform(.95),g.log("[ModalManager] ๐ŸŽญ Container transform set to scale(0.95)")),document.body.style.overflow="",g.log("[ModalManager] ๐ŸŽญ Body scroll restored")}_destroyModal(){g.log("[ModalManager] ๐Ÿ—‘๏ธ _destroyModal() called, waiting 300ms for animation"),setTimeout(()=>{g.log("[ModalManager] ๐Ÿ—‘๏ธ Animation complete, removing from DOM"),this.overlay&&this.overlay.parentNode&&(this.overlay.parentNode.removeChild(this.overlay),g.log("[ModalManager] ๐Ÿ—‘๏ธ Overlay removed from DOM")),this.overlay=null,this.container=null,this.iframe=null,this.closeButton=null,g.log("[ModalManager] โœ… Modal destroyed")},300)}_attachEventListeners(){}_removeEventListeners(){this.escapeListener&&(document.removeEventListener("keydown",this.escapeListener),this.escapeListener=null)}_handleCloseClick(e){e.stopPropagation(),this.onClose&&this.onClose("user_closed")}_handleOverlayClick(e){e.target===this.overlay&&this.onClose&&this.onClose("user_closed")}_handleEscapeKey(e){"Escape"===e.key&&this.isOpen&&this.onClose&&this.onClose("user_closed")}getIframe(){return this.iframe}getIsOpen(){return this.isOpen}}class E{constructor(e={}){if("undefined"==typeof window||"undefined"==typeof document)throw new Error("Dropp Payment SDK can only be used in a browser environment");if(!e.merchantId||!e.apiKey||!e.packageName)throw new Error("merchantId, apiKey, and packageName are required to initialize SDK");if(this.merchantId=e.merchantId,this.apiKey=e.apiKey,this.packageName=e.packageName,this.environment=e.environment||i.QA,this.baseUrl=e.paymentAppUrl||e.baseUrl||s[this.environment],this.isInitialized=!1,this.initializationPromise=null,this.getServerAuthToken="function"==typeof e.getServerAuthToken?e.getServerAuthToken:null,this.requireServerAuthToken="boolean"==typeof e.requireServerAuthToken?e.requireServerAuthToken:this.environment===i.PRODUCTION,this.allowLocalCallbacksInNonProd=!!e.allowLocalCallbacksInNonProd,e.allowedOrigins?.length)this.allowedOrigins=e.allowedOrigins;else try{this.allowedOrigins=[new URL(this.baseUrl).origin]}catch{this.allowedOrigins=o[this.environment]||[]}this.isOpen=!1,this.currentSession=null,this.currentFlowType=null,this.initTimeout=null,this.paymentTimeout=null,this.messageHandler=null,this.modalManager=null,g.setEnvironment(this.environment,{enabled:!!e.debugLogging}),g.log(`[Dropp SDK] Initialized v${m} - Environment: ${this.environment}`)}pay(e={}){return new Promise((t,n)=>{if(this.isOpen){const e=b(h,"A payment session is already in progress",{currentSession:this.currentSession});return void n(e)}(async()=>{try{await this.initialize();const i=v(e,{environment:this.environment,allowLocalCallbacksInNonProd:this.allowLocalCallbacksInNonProd});if(!i.valid){const e=b(p,"Invalid payment configuration",{errors:i.errors});return void n(e)}this.onSuccess=e.onSuccess||null,this.onFailure=e.onFailure||null,this.onCancel=e.onCancel||null,this.onClose=e.onClose||null,this.currentSession={resolve:t,reject:n,options:e,startTime:Date.now()},await this._initializePayment(e)}catch(e){const t=e&&e.code===p?e:b(u,"Failed to initialize payment",{originalError:e?.message||String(e)});n(t),this._cleanup()}})()})}async initialize(){return this.initializationPromise||(this.initializationPromise=(async()=>(await this._validateInitializationCredentials(),this.isInitialized=!0,{status:"success",code:"INITIALIZED",message:"Dropp SDK initialized successfully"}))().catch(e=>{throw this.isInitialized=!1,this.initializationPromise=null,e})),this.initializationPromise}_getValidationUrl(){const e={[i.QA]:"https://main.qa.dropp.cc/payer/webview/validate",[i.SANDBOX]:"https://sandbox.api.dropp.cc/payer/webview/validate",[i.PRODUCTION]:"https://api.dropp.cc/payer/webview/validate"};return e[this.environment]||e[i.QA]}async _validateInitializationCredentials(){const e=this._getValidationUrl();let t,n=null;try{t=await fetch(e,{method:"POST",headers:{accept:"application/json, text/plain, */*","content-type":"application/json","x-api-key":this.apiKey,"x-app-package":this.packageName},body:JSON.stringify({id:this.merchantId})})}catch(t){throw b(p,"Unable to validate merchant credentials",{endpoint:e,originalError:t?.message||String(t)})}try{n=await t.json()}catch{n=null}if(!t.ok)throw b(p,"Merchant validation failed for merchantId/apiKey/packageName",{endpoint:e,status:t.status,response:n});const i=Number(n?.responseCode),s=n?.errors,o=!Array.isArray(s)||0===s.length;if(!(n&&0===i&&o))throw b(p,"Merchant validation returned an unsuccessful response",{endpoint:e,status:t.status,response:n});g.log("[Dropp SDK] Merchant credentials validated successfully")}closePayment(){if(this.isOpen){if("page"===this.currentFlowType)return void this._cleanup();this._handleCancel("sdk_close")}}openDashboard(e={}){return this._openHostedPage("/firsttimeflow",e)}unlinkAccount(e={}){return this._openHostedPage("/unlink",e)}loadTransactions(e={}){return this._openHostedPage("/transactions",e)}loadOffers(e={}){return this._openHostedPage("/offers",e)}async _initializePayment(e){g.log("[Dropp SDK] Initializing payment session"),this.currentFlowType="payment",this.messageHandler=new w(this.environment,this._handleMessage.bind(this),this.allowedOrigins),this.modalManager=new T(this._handleModalClose.bind(this));const t=this.modalManager.open();if(!t)throw new Error("Failed to create modal iframe");this.messageHandler.init(t);const n=e.paymentType||l.STANDARD;let i="/payViaUrl";n===l.PREAUTH?i="/preAuthPayment":n===l.RECURRING&&(i="/recurringPayment");const s=n===l.RECURRING?(e.frequency||e.recurringInterval||"").toString().trim().toUpperCase():"",o=n===l.RECURRING&&"NONE"===s,c=e.appUrl||("undefined"!=typeof window&&window.location?window.location.href:void 0),d={merchantAccount:this.merchantId,amount:n===l.PREAUTH?void 0:e.amount,maxAmount:n===l.PREAUTH||o?e.amount:void 0,fixAmount:n!==l.RECURRING||o?void 0:e.amount,acceptPaymentDelay:n===l.STANDARD&&!0===e.acceptPaymentDelay||void 0,currency:e.currency,itemName:e.itemName,description:e.description,invoiceId:e.invoiceId||`INV-${Date.now()}`,invoiceType:n===l.PREAUTH?"PREAUTH":void 0,apiKey:this.apiKey,packageName:this.packageName,sdkVersion:m,platform:"web",appUrl:c,sessionId:this.messageHandler.getSessionId()};if(g.log("[Dropp SDK] Including SDK session context in payment params"),e.successURL&&(d.successURL=e.successURL),e.failureURL&&(d.failureURL=e.failureURL),n===l.RECURRING){const t=e.frequency||e.recurringInterval;t&&(d.frequency=t),e.recurringEndDate&&(d.expiry=e.recurringEndDate)}n===l.PREAUTH&&e.authHoldTimeInSeconds&&(d.authHoldTimeInSeconds=e.authHoldTimeInSeconds),e.callbackUrl&&(d.url=e.callbackUrl,d.submitToCallBack="post");const h={sessionId:d.sessionId,merchantAccount:this.merchantId,amount:e.amount,paymentType:n,invoiceId:d.invoiceId,expiry:e.recurringEndDate||null,issuedAt:Date.now()};let u="string"==typeof e.serverAuthToken?e.serverAuthToken.trim():"";if(!u&&this.getServerAuthToken)try{const e=await this.getServerAuthToken(h);u="string"==typeof e?e.trim():""}catch(e){throw b(p,"Failed to obtain server auth token",{originalError:e?.message||String(e)})}if(this.requireServerAuthToken&&!u)throw b(p,"serverAuthToken is required. Provide options.serverAuthToken or config.getServerAuthToken.",{environment:this.environment,paymentType:n,invoiceId:d.invoiceId});const y=await async function(e,t,n,i,s={}){try{const{serverAuthToken:o=""}=s,r={};Object.keys(n).forEach(e=>{const t=n[e];null!=t&&(r[e]=t)}),g.log("[buildPaymentUrl] Building payment URL payload");const a=JSON.stringify(r),l=btoa(a).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""),c=Date.now().toString(),d=new URLSearchParams({pay:l,sdkTs:c,sdkVersion:i,platform:"web"});return o&&d.set("authToken",o),`${e}/#${t}?${d.toString()}`}catch(e){throw g.error("Error building payment URL:",e),e}}(this.baseUrl,i,d,m,{serverAuthToken:u});g.log("[Dropp SDK] Loading payment flow iframe"),t.src=y,this.isOpen=!0,this.initTimeout=setTimeout(()=>{this._handleTimeout("init")},r),this.paymentTimeout=setTimeout(()=>{this._handleTimeout("payment")},a)}async _openHostedPage(e,t={}){if(this.isOpen)throw b(h,"A Dropp session is already in progress",{currentSession:this.currentSession,route:e});await this.initialize(),this.currentFlowType="page",this.currentSession=null,this.onSuccess=null,this.onFailure=null,this.onCancel=null,this.onClose="function"==typeof t.onClose?t.onClose:null,this.modalManager=new T(this._handleModalClose.bind(this));const n=this.modalManager.open();if(!n)throw new Error("Failed to create modal iframe");const i=this.baseUrl.replace(/\/+$/,"");return n.src=`${i}/#${e}`,this.isOpen=!0,g.log("[Dropp SDK] Hosted page opened",{route:e}),{status:"opened",route:e}}_handleMessage(t){const{type:n,data:i}=t;switch(n){case e.READY:this._handleReady(i);break;case e.PAYMENT_PAGE_LOADED:this._handlePageLoaded(i);break;case e.PAYMENT_SUCCESS:this._handleSuccess(i);break;case e.PAYMENT_FAILED:this._handleFailure(i);break;case e.PAYMENT_CANCELLED:this._handleCancel("user_cancelled");break;case e.AUTO_CLOSE_WEBVIEW:g.log("[Dropp SDK] AUTO_CLOSE_WEBVIEW received - closing modal"),this._cleanup(),g.log("[Dropp SDK] Cleanup completed");break;case e.CLOSE_WEBVIEW:g.log("[Dropp SDK] CLOSE_WEBVIEW received from app - closing modal"),this._handleCancel("app_close");break;default:g.warn("[Dropp SDK] Unknown message type:",n)}}_handleReady(e){if(g.log("[Dropp SDK] Payment app ready"),this.initTimeout&&(clearTimeout(this.initTimeout),this.initTimeout=null),this.messageHandler&&this.currentSession){const e={};Object.keys(this.currentSession.options).forEach(t=>{const n=this.currentSession.options[t];"function"!=typeof n&&(e[t]=n)}),g.log("[Dropp SDK] Sending init config to payment app"),this.messageHandler.sendInit(e)}}_handlePageLoaded(e){g.log("[Dropp SDK] Payment page loaded")}_handleSuccess(e){g.log("[Dropp SDK] Payment successful");const t={status:"success",...e,sessionDuration:Date.now()-this.currentSession.startTime};this.currentSession&&this.currentSession.resolve(t),this.onSuccess&&this.onSuccess(t)}_handleFailure(e){g.log("[Dropp SDK] Payment failed");const t={status:"failed",...e,sessionDuration:Date.now()-this.currentSession.startTime};this.currentSession&&this.currentSession.resolve(t),this.onFailure&&this.onFailure(t)}_handleCancel(e){g.log("[Dropp SDK] Payment cancelled");const t={status:"cancelled",reason:e,sessionDuration:this.currentSession?Date.now()-this.currentSession.startTime:0};this.currentSession&&this.currentSession.resolve(t),this.onCancel&&this.onCancel(t),this._cleanup()}_handleModalClose(e){g.log("[Dropp SDK] Modal closed by user"),"page"!==this.currentFlowType?this._handleCancel(e):this._cleanup()}_handleTimeout(e){g.error("[Dropp SDK] Timeout:",e);const t=b("init"===e?c:d,"init"===e?"Payment app failed to load within timeout period":"Payment session timed out",{type:e,sessionDuration:this.currentSession?Date.now()-this.currentSession.startTime:0});this.currentSession&&this.currentSession.reject(t),this.onFailure&&this.onFailure({status:"failed",error:t}),this._cleanup()}_cleanup(){g.log("[Dropp SDK] ๐Ÿงน Cleaning up session - starting cleanup"),this.initTimeout&&(clearTimeout(this.initTimeout),this.initTimeout=null),this.paymentTimeout&&(clearTimeout(this.paymentTimeout),this.paymentTimeout=null),this.messageHandler&&(g.log("[Dropp SDK] ๐Ÿงน Destroying message handler"),this.messageHandler.destroy(),this.messageHandler=null),this.modalManager&&(g.log("[Dropp SDK] ๐Ÿงน Closing modal manager"),this.modalManager.close(),g.log("[Dropp SDK] ๐Ÿงน Modal manager closed"),this.modalManager=null),this.currentSession=null,this.currentFlowType=null,this.isOpen=!1,this.onClose&&this.onClose()}static getVersion(){return m}static getEnvironments(){return{...i}}static getPaymentTypes(){return{...l}}}let _=null;async function I(e){_=new E(e);return{...await _.initialize(),sdk:_}}function A(){return _}const C={init:e=>I(e),pay(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.pay(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.pay(e)},openDashboard(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.openDashboard(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.openDashboard(e)},unlinkAccount(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.unlinkAccount(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.unlinkAccount(e)},loadTransactions(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.loadTransactions(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.loadTransactions(e)},loadOffers(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.loadOffers(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.loadOffers(e)},getInstance:()=>_};var N={DroppPaymentSDK:E,createPaymentSDK:I,Dropp:C,ENVIRONMENTS:i,PAYMENT_TYPES:l};export{C as Dropp,E as DroppPaymentSDK,i as ENVIRONMENTS,l as PAYMENT_TYPES,I as createPaymentSDK,N as default,A as getDroppInstance};
1
+ const e={READY:"DROPP_SDK_READY",PAYMENT_SUCCESS:"PAYMENT_SUCCESS",PAYMENT_FAILED:"PAYMENT_FAILED",PAYMENT_CANCELLED:"PAYMENT_CANCELLED",CLOSE_WEBVIEW:"CLOSE_WEBVIEW",AUTO_CLOSE_WEBVIEW:"AUTO_CLOSE_WEBVIEW",PAYMENT_PAGE_LOADED:"PAYMENT_PAGE_LOADED"},t="DROPP_SDK_INIT",n="DROPP_SDK_CLOSE",i={PRODUCTION:"production",QA:"qa",SANDBOX:"sandbox"},s={[i.PRODUCTION]:"https://wv.dropp.cc",[i.QA]:"https://wv.qa.dropp.cc",[i.SANDBOX]:"https://wv.sandbox.dropp.cc"},r={[i.PRODUCTION]:["https://wv.dropp.cc"],[i.QA]:["https://wv.qa.dropp.cc"],[i.SANDBOX]:["https://wv.sandbox.dropp.cc"]},o=3e4,a=6e5,l={STANDARD:"standard",PREAUTH:"preauth",RECURRING:"recurring"},c="INIT_TIMEOUT",d="PAYMENT_TIMEOUT",p="INVALID_CONFIG",h="ALREADY_OPEN",u="UNKNOWN_ERROR",m="1.0.2";const g=new class{constructor(e,t={}){this.environment=e,this.forceEnabled=!!t.enabled,this.enabled=this._shouldEnableLogging()}_shouldEnableLogging(){return this.forceEnabled}setEnvironment(e,t={}){this.environment=e,"boolean"==typeof t.enabled&&(this.forceEnabled=t.enabled),this.enabled=this._shouldEnableLogging()}setEnabled(e){this.forceEnabled=!!e,this.enabled=this._shouldEnableLogging()}log(...e){this.enabled&&console.log(...e)}warn(...e){this.enabled&&console.warn(...e)}error(...e){this.enabled&&console.error(...e)}debug(...e){this.enabled&&console.debug(...e)}info(...e){this.enabled&&console.info(...e)}}("qa",{enabled:!1}),y=["USD","HBAR","USDC"],f=["NONE","HALF_HOURLY","HOURLY","DAILY","WEEKLY","MONTHLY","YEARLY"],D=[l.STANDARD,l.PREAUTH,l.RECURRING];function S(e,t={}){const{isProduction:n=!1,allowLocalCallbacksInNonProd:i=!1}=t;if("string"!=typeof e||!e.trim())return!1;try{const t=new URL(e.trim()),s="https:"===t.protocol;if(!("http:"===t.protocol)&&!s)return!1;return function(e){if(!e)return!1;const t=e.trim().toLowerCase();if("localhost"===t||"127.0.0.1"===t||"::1"===t||t.endsWith(".local"))return!0;if(!/^(\d{1,3}\.){3}\d{1,3}$/.test(t))return!1;const n=t.split(".").map(e=>Number(e));if(n.some(e=>Number.isNaN(e)||e<0||e>255))return!1;const[i,s]=n;return 10===i||127===i||172===i&&s>=16&&s<=31||192===i&&168===s||169===i&&254===s}(t.hostname)?!n&&i:!n||s}catch{return!1}}function v(e={},t={}){const n=[],i=e.paymentType||l.STANDARD,s="production"===(t.environment||"").toLowerCase(),r=!!t.allowLocalCallbacksInNonProd,o="string"==typeof e.currency?e.currency.trim().toUpperCase():"";if(D.includes(i)||n.push(`paymentType must be one of: ${D.join(", ")}`),void 0===e.amount||null===e.amount||""===e.amount?n.push("amount is required"):function(e){const t="number"==typeof e?e:parseFloat(e);return"number"==typeof t&&!Number.isNaN(t)&&t>0}(e.amount)||n.push("amount must be a positive number"),e.currency&&"string"==typeof e.currency&&e.currency.trim()?y.includes(o)||n.push(`currency must be one of: ${y.join(", ")}`):n.push("currency is required"),e.itemName&&"string"==typeof e.itemName&&e.itemName.trim()||n.push("itemName is required"),i===l.PREAUTH&&(o&&"USD"!==o&&n.push("currency must be USD for preauth payments"),e.callbackUrl&&String(e.callbackUrl).trim()?S(e.callbackUrl,{isProduction:s,allowLocalCallbacksInNonProd:r})||n.push(s?"callbackUrl must be HTTPS in production and cannot target loopback/private hosts":"callbackUrl must be a valid HTTP/HTTPS URL and cannot target loopback/private hosts unless explicitly enabled"):n.push("callbackUrl (signing URL) is required for preauth payments"),void 0===e.authHoldTimeInSeconds||null===e.authHoldTimeInSeconds||""===e.authHoldTimeInSeconds?n.push("authHoldTimeInSeconds is required for preauth payments"):function(e){const t="number"==typeof e?e:parseInt(e,10);return Number.isInteger(t)&&t>0}(e.authHoldTimeInSeconds)||n.push("authHoldTimeInSeconds must be a positive integer (seconds)")),i===l.RECURRING){e.callbackUrl&&String(e.callbackUrl).trim()?S(e.callbackUrl,{isProduction:s,allowLocalCallbacksInNonProd:r})||n.push(s?"callbackUrl must be HTTPS in production and cannot target loopback/private hosts":"callbackUrl must be a valid HTTP/HTTPS URL and cannot target loopback/private hosts unless explicitly enabled"):n.push("callbackUrl (signing URL) is required for recurring payments");const t=(e.frequency||e.recurringInterval||"").toString().trim().toUpperCase();t?f.includes(t)||n.push(`frequency must be one of: ${f.join(", ")}`):n.push("frequency is required for recurring payments"),e.recurringEndDate&&String(e.recurringEndDate).trim()?!function(e){if("string"!=typeof e||!e.trim())return!1;const t=new Date(e.trim());return!Number.isNaN(t.getTime())}(e.recurringEndDate)?n.push("recurringEndDate must be a valid ISO date-time string"):new Date(e.recurringEndDate.trim())<=new Date&&n.push("recurringEndDate must be in the future"):n.push("recurringEndDate (expiry) is required for recurring payments")}return{valid:0===n.length,errors:n}}function b(e,t,n={}){return{code:e,message:t,details:n,timestamp:(new Date).toISOString(),toString(){return this.message||"Dropp SDK error"}}}class w{constructor(e,t,n=null){this.environment=e,this.onMessage=t,this.sessionId=`dropp-sdk-${Date.now()}-${Math.random().toString(36).substring(2,15)}`,g.log("[MessageHandler] Session initialized"),this.iframe=null,this.allowedOrigins=n?.length>0?n:r[e]||[],this.messageListener=null,this.pendingMessages=new Map}init(e){this.iframe=e,this.messageListener=this._handleMessage.bind(this),window.addEventListener("message",this.messageListener)}destroy(){this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.iframe=null,this.pendingMessages.clear()}_handleMessage(e){if(g.log("[MessageHandler] Received postMessage event"),e.source===window)return void g.log("[MessageHandler] Ignoring message from self");if(!this._validateOrigin(e.origin))return void g.warn("[Dropp SDK] Rejected message from untrusted origin:",e.origin);if(!this.iframe||e.source!==this.iframe.contentWindow)return void g.warn("[Dropp SDK] Rejected message from unexpected source",{eventOrigin:e.origin});const t=e.data;this._validateMessageStructure(t)?t.sessionId&&t.sessionId!==this.sessionId?g.warn("[Dropp SDK] Rejected message with invalid session ID"):(g.log("[MessageHandler] Message passed validation"),this._processMessage(t)):g.warn("[Dropp SDK] Rejected message with invalid structure")}_validateOrigin(e){return!(!e.startsWith("http://localhost:")&&!e.startsWith("http://127.0.0.1:"))||this.allowedOrigins.includes(e)}_validateMessageStructure(t){if(!t||"object"!=typeof t)return!1;if(!t.type||"string"!=typeof t.type)return!1;return!!Object.values(e).includes(t.type)&&!!t.timestamp}_processMessage(e){g.log("[Dropp SDK] Received message:",e.type),this.onMessage&&this.onMessage(e)}sendToPaymentApp(e,t={}){if(!this.iframe||!this.iframe.contentWindow)return g.error("[Dropp SDK] Cannot send message: iframe not ready"),!1;const n={type:e,data:t,sessionId:this.sessionId,timestamp:(new Date).toISOString(),sdkVersion:"1.0.0"},i=this.allowedOrigins[0]||"*";try{return this.iframe.contentWindow.postMessage(n,i),g.log("[Dropp SDK] Sent message:",e),!0}catch(e){return g.error("[Dropp SDK] Error sending message:",e),!1}}sendInit(e){return this.sendToPaymentApp(t,{mode:"sdk",config:e})}sendClose(){return this.sendToPaymentApp(n,{})}getSessionId(){return this.sessionId}}class E{constructor(e){this.onClose=e,this.overlay=null,this.container=null,this.iframe=null,this.closeButton=null,this.isOpen=!1,this.escapeListener=null}open(){return this.isOpen?(g.warn("[Dropp SDK] Modal is already open"),null):(this._createModal(),this._attachEventListeners(),this._show(),this.isOpen=!0,this.iframe)}close(){g.log("[ModalManager] ๐Ÿšฆ close() called, isOpen:",this.isOpen),this.isOpen?(g.log("[ModalManager] ๐Ÿšฆ Hiding modal..."),this._hide(),g.log("[ModalManager] ๐Ÿšฆ Removing event listeners..."),this._removeEventListeners(),g.log("[ModalManager] ๐Ÿšฆ Destroying modal..."),this._destroyModal(),this.isOpen=!1,g.log("[ModalManager] โœ… Modal close sequence initiated")):g.log("[ModalManager] โš ๏ธ Modal is not open, skipping close")}_createModal(){this.overlay=document.createElement("div"),this.overlay.id="dropp-payment-overlay",this._applyOverlayStyles(this.overlay),this.container=document.createElement("div"),this.container.id="dropp-payment-container",this._applyContainerStyles(this.container),this.iframe=document.createElement("iframe"),this.iframe.id="dropp-payment-iframe",this.iframe.setAttribute("allow","payment"),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),this.iframe.setAttribute("referrerpolicy","no-referrer"),this.iframe.setAttribute("title","Dropp Payment"),this._applyIframeStyles(this.iframe),this.container.appendChild(this.iframe),this.overlay.appendChild(this.container),document.body.appendChild(this.overlay)}_applyOverlayStyles(e){Object.assign(e.style,{position:"fixed",inset:"0",width:"100vw",height:"100vh",margin:"0",padding:"20px",boxSizing:"border-box",backgroundColor:"rgba(0, 0, 0, 0.6)",zIndex:999999..toString(),display:"flex",alignItems:"center",justifyContent:"center",opacity:"0",transition:"opacity 0.3s ease",backdropFilter:"blur(4px)",overflow:"auto"})}_applyContainerStyles(e){const t=window.innerWidth<768;this._isMobile=t,Object.assign(e.style,{position:"relative",flex:"0 0 auto",alignSelf:"center",margin:"auto",width:"100%",maxWidth:t?"100%":"400px",height:t?"100%":"auto",minHeight:t?"100%":"800px",maxHeight:t?"100%":"min(1000px, calc(100vh - 40px))",backgroundColor:"#ffffff",borderRadius:t?"0":"16px",boxShadow:"0 20px 60px rgba(0, 0, 0, 0.3)",overflow:"hidden",transform:"scale(0.95)",transition:"transform 0.3s ease, opacity 0.3s ease",display:"flex",flexDirection:"column"})}_getContainerTransform(e){return`scale(${e})`}_applyCloseButtonStyles(e){Object.assign(e.style,{position:"absolute",top:"16px",right:"16px",zIndex:"10",width:"40px",height:"40px",border:"none",borderRadius:"50%",backgroundColor:"rgba(255, 255, 255, 0.9)",color:"#333",fontSize:"28px",lineHeight:"1",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.15)",transition:"all 0.2s ease",fontFamily:"Arial, sans-serif",padding:"0"}),e.addEventListener("mouseenter",()=>{Object.assign(e.style,{backgroundColor:"#f5f5f5",transform:"scale(1.1)"})}),e.addEventListener("mouseleave",()=>{Object.assign(e.style,{backgroundColor:"rgba(255, 255, 255, 0.9)",transform:"scale(1)"})})}_applyIframeStyles(e){const t=this._isMobile;Object.assign(e.style,{width:"100%",flex:"1 1 auto",minHeight:t?"100%":"min(520px, calc(90vh - 40px))",height:t?"100%":"min(520px, calc(90vh - 40px))",border:"none",display:"block"})}_show(){document.body.style.overflow="hidden",requestAnimationFrame(()=>{this.overlay&&(this.overlay.style.opacity="1"),this.container&&(this.container.style.transform=this._getContainerTransform(1))})}_hide(){g.log("[ModalManager] ๐ŸŽญ _hide() called"),this.overlay&&(this.overlay.style.opacity="0",g.log("[ModalManager] ๐ŸŽญ Overlay opacity set to 0")),this.container&&(this.container.style.transform=this._getContainerTransform(.95),g.log("[ModalManager] ๐ŸŽญ Container transform set to scale(0.95)")),document.body.style.overflow="",g.log("[ModalManager] ๐ŸŽญ Body scroll restored")}_destroyModal(){g.log("[ModalManager] ๐Ÿ—‘๏ธ _destroyModal() called, waiting 300ms for animation"),setTimeout(()=>{g.log("[ModalManager] ๐Ÿ—‘๏ธ Animation complete, removing from DOM"),this.overlay&&this.overlay.parentNode&&(this.overlay.parentNode.removeChild(this.overlay),g.log("[ModalManager] ๐Ÿ—‘๏ธ Overlay removed from DOM")),this.overlay=null,this.container=null,this.iframe=null,this.closeButton=null,g.log("[ModalManager] โœ… Modal destroyed")},300)}_attachEventListeners(){}_removeEventListeners(){this.escapeListener&&(document.removeEventListener("keydown",this.escapeListener),this.escapeListener=null)}_handleCloseClick(e){e.stopPropagation(),this.onClose&&this.onClose("user_closed")}_handleOverlayClick(e){e.target===this.overlay&&this.onClose&&this.onClose("user_closed")}_handleEscapeKey(e){"Escape"===e.key&&this.isOpen&&this.onClose&&this.onClose("user_closed")}getIframe(){return this.iframe}getIsOpen(){return this.isOpen}}class T{constructor(e={}){if("undefined"==typeof window||"undefined"==typeof document)throw new Error("Dropp Payment SDK can only be used in a browser environment");if(!e.merchantId||!e.apiKey||!e.packageName)throw new Error("merchantId, apiKey, and packageName are required to initialize SDK");if(this.merchantId=e.merchantId,this.apiKey=e.apiKey,this.packageName=e.packageName,this.environment=e.environment||i.QA,this.baseUrl=e.paymentAppUrl||e.baseUrl||s[this.environment],this.isInitialized=!1,this.initializationPromise=null,this.getServerAuthToken="function"==typeof e.getServerAuthToken?e.getServerAuthToken:null,this.requireServerAuthToken="boolean"==typeof e.requireServerAuthToken?e.requireServerAuthToken:this.environment===i.PRODUCTION,this.allowLocalCallbacksInNonProd=!!e.allowLocalCallbacksInNonProd,e.allowedOrigins?.length)this.allowedOrigins=e.allowedOrigins;else try{this.allowedOrigins=[new URL(this.baseUrl).origin]}catch{this.allowedOrigins=r[this.environment]||[]}this.isOpen=!1,this.currentSession=null,this.currentFlowType=null,this.initTimeout=null,this.paymentTimeout=null,this.messageHandler=null,this.modalManager=null,g.setEnvironment(this.environment,{enabled:!!e.debugLogging}),g.log(`[Dropp SDK] Initialized v${m} - Environment: ${this.environment}`)}pay(e={}){return new Promise((t,n)=>{if(this.isOpen){const e=b(h,"A payment session is already in progress",{currentSession:this.currentSession});return void n(e)}(async()=>{try{await this.initialize();const i=v(e,{environment:this.environment,allowLocalCallbacksInNonProd:this.allowLocalCallbacksInNonProd});if(!i.valid){const e=b(p,"Invalid payment configuration",{errors:i.errors});return void n(e)}this.onSuccess=e.onSuccess||null,this.onFailure=e.onFailure||null,this.onCancel=e.onCancel||null,this.onClose=e.onClose||null,this.currentSession={resolve:t,reject:n,options:e,startTime:Date.now()},await this._initializePayment(e)}catch(e){const t=e&&e.code===p?e:b(u,"Failed to initialize payment",{originalError:e?.message||String(e)});n(t),this._cleanup()}})()})}async initialize(){return this.initializationPromise||(this.initializationPromise=(async()=>(await this._validateInitializationCredentials(),this.isInitialized=!0,{status:"success",code:"INITIALIZED",message:"Dropp SDK initialized successfully"}))().catch(e=>{throw this.isInitialized=!1,this.initializationPromise=null,e})),this.initializationPromise}_getValidationUrl(){const e={[i.QA]:"https://main.qa.dropp.cc/payer/webview/validate",[i.SANDBOX]:"https://sandbox.api.dropp.cc/payer/webview/validate",[i.PRODUCTION]:"https://api.dropp.cc/payer/webview/validate"};return e[this.environment]||e[i.QA]}async _validateInitializationCredentials(){const e=this._getValidationUrl();let t,n=null;try{t=await fetch(e,{method:"POST",headers:{accept:"application/json, text/plain, */*","content-type":"application/json","x-api-key":this.apiKey,"x-app-package":this.packageName},body:JSON.stringify({id:this.merchantId})})}catch(t){throw b(p,"Unable to validate merchant credentials",{endpoint:e,originalError:t?.message||String(t)})}try{n=await t.json()}catch{n=null}if(!t.ok)throw b(p,"Merchant validation failed for merchantId/apiKey/packageName",{endpoint:e,status:t.status,response:n});const i=Number(n?.responseCode),s=n?.errors,r=!Array.isArray(s)||0===s.length;if(!(n&&0===i&&r))throw b(p,"Merchant validation returned an unsuccessful response",{endpoint:e,status:t.status,response:n});g.log("[Dropp SDK] Merchant credentials validated successfully")}closePayment(){if(this.isOpen){if("page"===this.currentFlowType)return void this._cleanup();this._handleCancel("sdk_close")}}dashboard(e={}){return this._openHostedPage("/firsttimeflow",e)}unlinkAccount(e={}){return this._openHostedPage("/unlink",e)}transactions(e={}){return this._openHostedPage("/transactions",e)}offers(e={}){return this._openHostedPage("/offers",e)}async _initializePayment(e){g.log("[Dropp SDK] Initializing payment session"),this.currentFlowType="payment",this.messageHandler=new w(this.environment,this._handleMessage.bind(this),this.allowedOrigins),this.modalManager=new E(this._handleModalClose.bind(this));const t=this.modalManager.open();if(!t)throw new Error("Failed to create modal iframe");this.messageHandler.init(t);const n=e.paymentType||l.STANDARD;let i="/payViaUrl";n===l.PREAUTH?i="/preAuthPayment":n===l.RECURRING&&(i="/recurringPayment");const s=n===l.RECURRING?(e.frequency||e.recurringInterval||"").toString().trim().toUpperCase():"",r=n===l.RECURRING&&"NONE"===s,c=e.appUrl||("undefined"!=typeof window&&window.location?window.location.href:void 0),d={merchantAccount:this.merchantId,amount:n===l.PREAUTH?void 0:e.amount,maxAmount:n===l.PREAUTH||r?e.amount:void 0,fixAmount:n!==l.RECURRING||r?void 0:e.amount,acceptPaymentDelay:n===l.STANDARD&&!0===e.acceptPaymentDelay||void 0,currency:e.currency,itemName:e.itemName,description:e.description,invoiceId:e.invoiceId||`INV-${Date.now()}`,invoiceType:n===l.PREAUTH?"PREAUTH":void 0,apiKey:this.apiKey,packageName:this.packageName,sdkVersion:m,platform:"web",appUrl:c,sessionId:this.messageHandler.getSessionId()};if(g.log("[Dropp SDK] Including SDK session context in payment params"),e.successURL&&(d.successURL=e.successURL),e.failureURL&&(d.failureURL=e.failureURL),n===l.RECURRING){const t=e.frequency||e.recurringInterval;t&&(d.frequency=t),e.recurringEndDate&&(d.expiry=e.recurringEndDate)}n===l.PREAUTH&&e.authHoldTimeInSeconds&&(d.authHoldTimeInSeconds=e.authHoldTimeInSeconds),e.callbackUrl&&(d.url=e.callbackUrl,d.submitToCallBack="post");const h={sessionId:d.sessionId,merchantAccount:this.merchantId,amount:e.amount,paymentType:n,invoiceId:d.invoiceId,expiry:e.recurringEndDate||null,issuedAt:Date.now()};let u="string"==typeof e.serverAuthToken?e.serverAuthToken.trim():"";if(!u&&this.getServerAuthToken)try{const e=await this.getServerAuthToken(h);u="string"==typeof e?e.trim():""}catch(e){throw b(p,"Failed to obtain server auth token",{originalError:e?.message||String(e)})}if(this.requireServerAuthToken&&!u)throw b(p,"serverAuthToken is required. Provide options.serverAuthToken or config.getServerAuthToken.",{environment:this.environment,paymentType:n,invoiceId:d.invoiceId});const y=await async function(e,t,n,i,s={}){try{const{serverAuthToken:r=""}=s,o={};Object.keys(n).forEach(e=>{const t=n[e];null!=t&&(o[e]=t)}),g.log("[buildPaymentUrl] Building payment URL payload");const a=JSON.stringify(o),l=btoa(a).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""),c=Date.now().toString(),d=new URLSearchParams({pay:l,sdkTs:c,sdkVersion:i,platform:"web"});return r&&d.set("authToken",r),`${e}/#${t}?${d.toString()}`}catch(e){throw g.error("Error building payment URL:",e),e}}(this.baseUrl,i,d,m,{serverAuthToken:u});g.log("[Dropp SDK] Loading payment flow iframe"),t.src=y,this.isOpen=!0,this.initTimeout=setTimeout(()=>{this._handleTimeout("init")},o),this.paymentTimeout=setTimeout(()=>{this._handleTimeout("payment")},a)}async _openHostedPage(e,t={}){if(this.isOpen)throw b(h,"A Dropp session is already in progress",{currentSession:this.currentSession,route:e});await this.initialize(),this.currentFlowType="page",this.currentSession=null,this.onSuccess=null,this.onFailure=null,this.onCancel=null,this.onClose="function"==typeof t.onClose?t.onClose:null,this.messageHandler=new w(this.environment,this._handleMessage.bind(this),this.allowedOrigins),this.modalManager=new E(this._handleModalClose.bind(this));const n=this.modalManager.open();if(!n)throw new Error("Failed to create modal iframe");this.messageHandler.init(n);const i=this.baseUrl.replace(/\/+$/,"");return n.src=`${i}/#${e}`,this.isOpen=!0,g.log("[Dropp SDK] Hosted page opened",{route:e}),{status:"opened",route:e}}_handleMessage(t){const{type:n,data:i}=t;switch(n){case e.READY:this._handleReady(i);break;case e.PAYMENT_PAGE_LOADED:this._handlePageLoaded(i);break;case e.PAYMENT_SUCCESS:this._handleSuccess(i);break;case e.PAYMENT_FAILED:this._handleFailure(i);break;case e.PAYMENT_CANCELLED:this._handleCancel("user_cancelled");break;case e.AUTO_CLOSE_WEBVIEW:g.log("[Dropp SDK] AUTO_CLOSE_WEBVIEW received - closing modal"),this._cleanup(),g.log("[Dropp SDK] Cleanup completed");break;case e.CLOSE_WEBVIEW:g.log("[Dropp SDK] CLOSE_WEBVIEW received from app - closing modal"),this._handleCancel("app_close");break;default:g.warn("[Dropp SDK] Unknown message type:",n)}}_handleReady(e){if(g.log("[Dropp SDK] Payment app ready"),this.initTimeout&&(clearTimeout(this.initTimeout),this.initTimeout=null),this.messageHandler&&this.currentSession){const e={};Object.keys(this.currentSession.options).forEach(t=>{const n=this.currentSession.options[t];"function"!=typeof n&&(e[t]=n)}),g.log("[Dropp SDK] Sending init config to payment app"),this.messageHandler.sendInit(e)}}_handlePageLoaded(e){g.log("[Dropp SDK] Payment page loaded")}_handleSuccess(e){g.log("[Dropp SDK] Payment successful");const t={status:"success",...e,sessionDuration:Date.now()-this.currentSession.startTime};this.currentSession&&this.currentSession.resolve(t),this.onSuccess&&this.onSuccess(t)}_handleFailure(e){g.log("[Dropp SDK] Payment failed");const t={status:"failed",...e,sessionDuration:Date.now()-this.currentSession.startTime};this.currentSession&&this.currentSession.resolve(t),this.onFailure&&this.onFailure(t)}_handleCancel(e){g.log("[Dropp SDK] Payment cancelled");const t={status:"cancelled",reason:e,sessionDuration:this.currentSession?Date.now()-this.currentSession.startTime:0};this.currentSession&&this.currentSession.resolve(t),this.onCancel&&this.onCancel(t),this._cleanup()}_handleModalClose(e){g.log("[Dropp SDK] Modal closed by user"),"page"!==this.currentFlowType?this._handleCancel(e):this._cleanup()}_handleTimeout(e){g.error("[Dropp SDK] Timeout:",e);const t=b("init"===e?c:d,"init"===e?"Payment app failed to load within timeout period":"Payment session timed out",{type:e,sessionDuration:this.currentSession?Date.now()-this.currentSession.startTime:0});this.currentSession&&this.currentSession.reject(t),this.onFailure&&this.onFailure({status:"failed",error:t}),this._cleanup()}_cleanup(){g.log("[Dropp SDK] ๐Ÿงน Cleaning up session - starting cleanup"),this.initTimeout&&(clearTimeout(this.initTimeout),this.initTimeout=null),this.paymentTimeout&&(clearTimeout(this.paymentTimeout),this.paymentTimeout=null),this.messageHandler&&(g.log("[Dropp SDK] ๐Ÿงน Destroying message handler"),this.messageHandler.destroy(),this.messageHandler=null),this.modalManager&&(g.log("[Dropp SDK] ๐Ÿงน Closing modal manager"),this.modalManager.close(),g.log("[Dropp SDK] ๐Ÿงน Modal manager closed"),this.modalManager=null),this.currentSession=null,this.currentFlowType=null,this.isOpen=!1,this.onClose&&this.onClose()}static getVersion(){return m}static getEnvironments(){return{...i}}static getPaymentTypes(){return{...l}}}let _=null;async function I(e){_=new T(e);return{...await _.initialize(),sdk:_}}function A(){return _}const C={init:e=>I(e),pay(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.pay(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.pay(e)},dashboard(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.dashboard(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.dashboard(e)},unlinkAccount(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.unlinkAccount(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.unlinkAccount(e)},transactions(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.transactions(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.transactions(e)},offers(e){if(!_){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.offers(options).");throw e.code="SDK_NOT_INITIALIZED",e}return _.offers(e)},getInstance:()=>_};var N={DroppPaymentSDK:T,createPaymentSDK:I,Dropp:C,ENVIRONMENTS:i,PAYMENT_TYPES:l};export{C as Dropp,T as DroppPaymentSDK,i as ENVIRONMENTS,l as PAYMENT_TYPES,I as createPaymentSDK,N as default,A as getDroppInstance};
2
2
  //# sourceMappingURL=dropp-payment-sdk.esm.js.map