@dropp.cc/payment-sdk 1.0.27 โ 1.0.29
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
|
@@ -311,7 +311,7 @@ const result = await Dropp.pay({
|
|
|
311
311
|
itemName: 'Premium Product',
|
|
312
312
|
paymentType: 'standard',
|
|
313
313
|
description: 'One-time product purchase',
|
|
314
|
-
|
|
314
|
+
reference: 'ORDER-12345'
|
|
315
315
|
});
|
|
316
316
|
```
|
|
317
317
|
|
|
@@ -324,7 +324,7 @@ const result = await Dropp.pay({
|
|
|
324
324
|
| `currency` | string | Yes | Currency code such as `USD`. |
|
|
325
325
|
| `itemName` | string | Yes | Name of the purchased item/service. |
|
|
326
326
|
| `description` | string | No | Payment description. |
|
|
327
|
-
| `
|
|
327
|
+
| `reference` | string | No (recommended) | Merchant order/reference identifier. If omitted, SDK generates `INV-<timestamp>`. |
|
|
328
328
|
| `acceptPaymentDelay` | boolean | No | Allows delayed payment processing. Default is false when not supplied. |
|
|
329
329
|
| `noOffers` | boolean | No | Disables promotional offers when set to true. |
|
|
330
330
|
| `isSkipCrypto` | boolean \| null | No | Controls whether the cryptocurrency payment option is skipped. |
|
|
@@ -377,7 +377,7 @@ const result = await Dropp.pay({
|
|
|
377
377
|
itemName: 'Hotel Reservation',
|
|
378
378
|
paymentType: 'preauth',
|
|
379
379
|
description: 'Hotel reservation authorization',
|
|
380
|
-
|
|
380
|
+
reference: 'RESERVATION-12345',
|
|
381
381
|
authHoldTimeInSeconds: 3600,
|
|
382
382
|
callbackUrl: 'https://merchant.example.com/pre-auth-post-callback'
|
|
383
383
|
});
|
|
@@ -392,7 +392,7 @@ const result = await Dropp.pay({
|
|
|
392
392
|
| `currency` | string | Yes | Currency code. |
|
|
393
393
|
| `itemName` | string | Yes | Authorization name. |
|
|
394
394
|
| `description` | string | No | Authorization description. |
|
|
395
|
-
| `
|
|
395
|
+
| `reference` | string | No (recommended) | Merchant order/reference identifier. If omitted, SDK generates `INV-<timestamp>`. |
|
|
396
396
|
| `authHoldTimeInSeconds` | number | Yes | Duration for which the authorization remains valid. |
|
|
397
397
|
| `callbackUrl` | string | Yes | Public HTTPS endpoint on the merchant backend used for the callback request/response contract. |
|
|
398
398
|
|
|
@@ -498,7 +498,7 @@ const result = await Dropp.pay({
|
|
|
498
498
|
itemName: 'Monthly Subscription',
|
|
499
499
|
paymentType: 'recurring',
|
|
500
500
|
description: 'Monthly subscription',
|
|
501
|
-
|
|
501
|
+
reference: 'SUBSCRIPTION-12345',
|
|
502
502
|
callbackUrl: 'https://merchant.example.com/rps-callback',
|
|
503
503
|
recurringEndDate: new Date(
|
|
504
504
|
Date.now() + 365 * 24 * 60 * 60 * 1000
|
|
@@ -516,7 +516,7 @@ const result = await Dropp.pay({
|
|
|
516
516
|
| `frequency` | RecurringInterval \| null | Conditional | Recurring interval. When supplied, amount is treated as a fixed amount; otherwise it represents the maximum amount according to the documented behavior. |
|
|
517
517
|
| `itemName` | string | Yes | Subscription name. |
|
|
518
518
|
| `description` | string | No | Payment description. |
|
|
519
|
-
| `
|
|
519
|
+
| `reference` | string | No (recommended) | Merchant order/reference identifier. If omitted, SDK generates `INV-<timestamp>`. |
|
|
520
520
|
| `recurringEndDate` | string | Yes | Expiry date in ISO-8601 format. |
|
|
521
521
|
| `callbackUrl` | string | Yes | Public HTTPS backend callback endpoint. |
|
|
522
522
|
|
|
@@ -1211,7 +1211,6 @@ A Standard Payment returns a response similar to:
|
|
|
1211
1211
|
title: 'Payment Successful!',
|
|
1212
1212
|
message: 'Payment successful!',
|
|
1213
1213
|
transactionId: 'ABCS-38947835',
|
|
1214
|
-
invoiceId: 'ABC-29388474',
|
|
1215
1214
|
reference: 'ORDER-12345',
|
|
1216
1215
|
merchantAccount: '0.0.100010',
|
|
1217
1216
|
amount: 50,
|
|
@@ -1259,7 +1258,6 @@ A successful PreAuth response is similar to:
|
|
|
1259
1258
|
message: 'Pre-auth approved successfully!',
|
|
1260
1259
|
transactionId: 'ABCD-1238838',
|
|
1261
1260
|
reference: 'RESERVATION-12345',
|
|
1262
|
-
invoiceId: 'ABCD-20384774',
|
|
1263
1261
|
merchantAccount: '0.0.001000',
|
|
1264
1262
|
amount: 50,
|
|
1265
1263
|
currency: 'USD',
|
|
@@ -1298,9 +1296,8 @@ A successful recurring response is similar to:
|
|
|
1298
1296
|
title: 'Recurring Approved!',
|
|
1299
1297
|
message: 'Recurring payment approved successfully!',
|
|
1300
1298
|
transactionId: '1687-20260602',
|
|
1301
|
-
recurringToken:
|
|
1302
|
-
reference:
|
|
1303
|
-
invoiceId: 'INV-RECURRING-1780388213609',
|
|
1299
|
+
recurringToken: '73878483333',
|
|
1300
|
+
reference: 'SUBSCRIPTION-1780388213609',
|
|
1304
1301
|
receiptURL: 'https://qa.pay.dropp.cc/receipts/1687-20260602',
|
|
1305
1302
|
timestamp: '2026-06-02T08:17:03.539270201Z',
|
|
1306
1303
|
merchantAccount: '0.0.4646049',
|
|
@@ -1442,7 +1439,7 @@ function App() {
|
|
|
1442
1439
|
itemName: 'Product Purchase',
|
|
1443
1440
|
paymentType: 'standard',
|
|
1444
1441
|
description: 'Product purchase',
|
|
1445
|
-
|
|
1442
|
+
reference: 'ORDER-12345'
|
|
1446
1443
|
});
|
|
1447
1444
|
|
|
1448
1445
|
console.log(result);
|
|
@@ -1490,7 +1487,7 @@ const result = await Dropp.pay({
|
|
|
1490
1487
|
itemName: 'One-time Purchase',
|
|
1491
1488
|
paymentType: 'standard',
|
|
1492
1489
|
description: 'One-time purchase',
|
|
1493
|
-
|
|
1490
|
+
reference: 'ORDER-12345'
|
|
1494
1491
|
});
|
|
1495
1492
|
```
|
|
1496
1493
|
|
|
@@ -1547,7 +1544,7 @@ async function pay() {
|
|
|
1547
1544
|
itemName: 'Product Purchase',
|
|
1548
1545
|
paymentType: 'standard',
|
|
1549
1546
|
description: 'Product purchase',
|
|
1550
|
-
|
|
1547
|
+
reference: 'ORDER-12345'
|
|
1551
1548
|
});
|
|
1552
1549
|
|
|
1553
1550
|
if (result?.status === 'success' || result?.success === true) {
|
|
@@ -2049,8 +2046,7 @@ Known limits to account for in product design/testing:
|
|
|
2049
2046
|
|
|
2050
2047
|
1. PreAuth hold duration is time-limited and should be treated as short-lived authorization.
|
|
2051
2048
|
2. `authHoldTimeInSeconds` is typically constrained to 86400 seconds (24 hours).
|
|
2052
|
-
3.
|
|
2053
|
-
4. Concurrent SDK flows are blocked by single-session locking (`ALREADY_OPEN`).
|
|
2049
|
+
3. Concurrent SDK flows are blocked by single-session locking (`ALREADY_OPEN`).
|
|
2054
2050
|
|
|
2055
2051
|
Validate these constraints in your target environment before go-live.
|
|
2056
2052
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e={READY:"DROPP_SDK_READY",PAYMENT_SUCCESS:"PAYMENT_SUCCESS",PAYMENT_FAILED:"PAYMENT_FAILED",PAYMENT_CANCELLED:"PAYMENT_CANCELLED",ACCOUNT_EVENT:"ACCOUNT_EVENT",PAGE_EVENT:"PAGE_EVENT",ACCOUNT_STATUS:"ACCOUNT_STATUS",CLOSE_WEBVIEW:"CLOSE_WEBVIEW",AUTO_CLOSE_WEBVIEW:"AUTO_CLOSE_WEBVIEW",PAYMENT_PAGE_LOADED:"PAYMENT_PAGE_LOADED",PAGE_LOADED:"PAGE_LOADED"},t="DROPP_SDK_INIT",n="DROPP_SDK_CLOSE",s={PRODUCTION:"production",QA:"qa",SANDBOX:"sandbox"},i={[s.PRODUCTION]:"https://wv.dropp.cc",[s.QA]:"https://wv.qa.dropp.cc",[s.SANDBOX]:"https://wv.sandbox.dropp.cc"},o={[s.PRODUCTION]:["https://wv.dropp.cc"],[s.QA]:["https://wv.qa.dropp.cc"],[s.SANDBOX]:["https://wv.sandbox.dropp.cc"]},r=3e4,a=6e5,l={STANDARD:"standard",PREAUTH:"preauth",RECURRING:"recurring"},c="INIT_TIMEOUT",u="PAYMENT_TIMEOUT",d="INVALID_CONFIG",h="ALREADY_OPEN",p="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}),f=["USD","HBAR","USDC"],y=["NONE","HALF_HOURLY","HOURLY","DAILY","WEEKLY","MONTHLY","YEARLY"],D=[l.STANDARD,l.PREAUTH,l.RECURRING];function S(e,t={}){const{isProduction:n=!1,allowLocalCallbacksInNonProd:s=!1}=t;if("string"!=typeof e||!e.trim())return!1;try{const t=new URL(e.trim()),i="https:"===t.protocol;if(!("http:"===t.protocol)&&!i)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[s,i]=n;return 10===s||127===s||172===s&&i>=16&&i<=31||192===s&&168===i||169===s&&254===i}(t.hostname)?!n&&s:!n||i}catch{return!1}}function w(e){return function(e){const t="string"==typeof e?e:String(e??"");if("undefined"!=typeof TextEncoder){const e=(new TextEncoder).encode(t);let n="";return e.forEach(e=>{n+=String.fromCharCode(e)}),btoa(n)}return btoa(unescape(encodeURIComponent(t)))}(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function T(e={},t={}){const n=[],s=e.paymentType||l.STANDARD,i="production"===(t.environment||"").toLowerCase(),o=!!t.allowLocalCallbacksInNonProd,r="string"==typeof e.currency?e.currency.trim().toUpperCase():"";if(D.includes(s)||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()?f.includes(r)||n.push(`currency must be one of: ${f.join(", ")}`):n.push("currency is required"),e.itemName&&"string"==typeof e.itemName&&e.itemName.trim()||n.push("itemName is required"),s===l.PREAUTH&&(r&&"USD"!==r&&n.push("currency must be USD for preauth payments"),e.callbackUrl&&String(e.callbackUrl).trim()?S(e.callbackUrl,{isProduction:i,allowLocalCallbacksInNonProd:o})||n.push(i?"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)")),s===l.RECURRING){e.callbackUrl&&String(e.callbackUrl).trim()?S(e.callbackUrl,{isProduction:i,allowLocalCallbacksInNonProd:o})||n.push(i?"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?y.includes(t)||n.push(`frequency must be one of: ${y.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 _{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.type!==e.ACCOUNT_STATUS&&!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"},s=this.allowedOrigins[0]||"*";try{return this.iframe.contentWindow.postMessage(n,s),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 v{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}}const E=["fundnow","linkbank","linkcard","redeemnow","fundcrypto","transferusdc","usdchistory","redeemcrypto","manageaccounts","transactions","merchantlist","favorites","offers","profile","pinchange","unlinkaccount","accountsettings","aboutus"];class A{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)throw new Error("merchantId and apiKey are required to initialize SDK");if(this.merchantId=e.merchantId,this.apiKey=e.apiKey,this.environment=e.environment||s.QA,this.baseUrl=e.paymentAppUrl||e.baseUrl||i[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===s.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.statusSession=null,this.hiddenIframe=null,this.statusTimeout=null,this.initTimeout=null,this.paymentTimeout=null,this.hostAppDomain=null,this.onAccountChanged=null,this.onPageFailed=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||this.currentFlowType){const e=b(h,"A payment session is already in progress",{currentSession:this.currentSession,currentFlowType:this.currentFlowType});return void n(e)}(async()=>{try{await this.initialize();const s=T(e,{environment:this.environment,allowLocalCallbacksInNonProd:this.allowLocalCallbacksInNonProd});if(!s.valid){const e=b(d,"Invalid payment configuration",{errors:s.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===d?e:b(p,"Failed to initialize payment",{originalError:e?.message||String(e)});n(t),this._cleanup()}})()})}async initialize(){return this.initializationPromise||(this.initializationPromise=(async()=>{if(this.hostAppDomain=this._detectHostAppDomain(),!this.hostAppDomain)throw b(d,"Unable to detect host app domain for SDK validation");return 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={[s.QA]:"https://bc0qfqi8c9.execute-api.us-east-1.amazonaws.com/QA-test-app-sdk-gateway-stage/sdk/payer/webview/validateSdk",[s.SANDBOX]:"https://76xbxsi4kf.execute-api.us-east-1.amazonaws.com/sandbox/sdk/payer/webview/validateSdk",[s.PRODUCTION]:"https://api.dropp.cc/payer/webview/validateSdk"};return e[this.environment]||e[s.QA]}_detectHostAppDomain(){if("undefined"!=typeof window&&window.location)return window.location.hostname||void 0}_getHostedPageAuthToken(){const e="string"==typeof this.apiKey?this.apiKey.trim():"",t="string"==typeof this.merchantId?this.merchantId.trim():"";if(!e)return"";try{return w(JSON.stringify({apikey:e,merchantAccount:t}))}catch{return""}}_formatValidationFailureMessage(e,t,n){const s=[e];Number.isFinite(t)&&s.push(`httpStatus=${t}`);const i=n?.responseCode,o=Number(i);Number.isNaN(o)||s.push(`responseCode=${o}`);let r="";if(Array.isArray(n?.errors)&&n.errors.length>0){const e=n.errors[0];r="string"==typeof e?e:e&&"string"==typeof e.message?e.message:JSON.stringify(e)}else"string"==typeof n?.message&&n.message.trim()&&(r=n.message.trim());return r&&s.push(`reason=${r}`),s.join(" | ")}async _validateInitializationCredentials(){const e=this._getValidationUrl(),t=this.hostAppDomain;if(!t)throw b(d,"Unable to resolve host app domain for SDK validation");const n={accept:"application/json, text/plain, */*","content-type":"application/json","x-api-key":this.apiKey,"x-app-package":t,"dropp-user-agent":"WEB"};let s;n["dropp-merchant-domain"]=t;let i=null;try{s=await fetch(e,{method:"POST",headers:n,body:JSON.stringify({id:this.merchantId})})}catch(t){throw b(d,"Unable to validate merchant credentials",{endpoint:e,originalError:t?.message||String(t)})}try{i=await s.json()}catch{i=null}if(!s.ok){const t=this._formatValidationFailureMessage("Merchant validation failed for merchantId/apiKey/domain",s.status,i);throw b(d,t,{endpoint:e,status:s.status,response:i})}const o=Number(i?.responseCode),r=i?.errors,a=!Array.isArray(r)||0===r.length;if(!(i&&0===o&&a)){const t=this._formatValidationFailureMessage("Merchant validation returned an unsuccessful response",s.status,i);throw b(d,t,{endpoint:e,status:s.status,response:i})}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)}open(e,t={}){const n="string"==typeof e?e.trim():"";if(!n)throw b(d,"moduleId is required for Dropp.open(moduleId)",{moduleId:e});if(!E.includes(n))throw b(d,"Unsupported moduleId passed to Dropp.open(moduleId)",{moduleId:n,supportedModuleIds:[...E]});const s="about"===n?"/aboutus":`/${n}`;return this._openHostedPage(s,t)}unlinkAccount(e={}){return this._openHostedPage("/unlink",e)}transactions(e={}){return this._openHostedPage("/transactions",e)}offers(e={}){return this._openHostedPage("/offers",e)}status(){return new Promise((e,t)=>{this.isOpen||this.currentFlowType?t(b(h,"A Dropp session is already in progress",{currentSession:this.currentSession,currentFlowType:this.currentFlowType})):(async()=>{try{this.currentFlowType="status",await this.initialize(),this.currentSession=null,this.onSuccess=null,this.onFailure=null,this.onCancel=null,this.onClose=null,this.messageHandler=new _(this.environment,this._handleMessage.bind(this),this.allowedOrigins);const n=document.createElement("iframe");n.id="dropp-status-iframe",n.setAttribute("allow","payment"),n.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),n.setAttribute("referrerpolicy","no-referrer"),n.setAttribute("title","Dropp Account Status"),Object.assign(n.style,{position:"absolute",width:"1px",height:"1px",border:"0",opacity:"0",pointerEvents:"none",visibility:"hidden"}),document.body.appendChild(n),this.hiddenIframe=n,this.messageHandler.init(n);const s=new URLSearchParams({sdkMode:"true",sessionId:this.messageHandler.getSessionId(),sdkVersion:m,platform:"web",merchantDomain:this.hostAppDomain}),i=this._getHostedPageAuthToken();i&&s.set("auth",i);const o=this.baseUrl.replace(/\/+$/,"");n.src=`${o}/#/status?${s.toString()}`,this.statusSession={resolve:e,reject:t,startTime:Date.now()},this.statusTimeout=setTimeout(()=>{const e=b(c,"Account status request timed out",{type:"status",sessionDuration:this.statusSession?Date.now()-this.statusSession.startTime:0});this.statusSession&&this.statusSession.reject(e),this._cleanup()},r)}catch(e){t(b(p,"Failed to get account status",{originalError:e?.message||String(e)})),this._cleanup()}})()})}async _initializePayment(e){g.log("[Dropp SDK] Initializing payment session"),this.currentFlowType="payment",this.messageHandler=new _(this.environment,this._handleMessage.bind(this),this.allowedOrigins),this.modalManager=new v(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 s="/payViaUrl";n===l.PREAUTH?s="/preAuthPayment":n===l.RECURRING&&(s="/recurringPayment");const i=n===l.RECURRING?(e.frequency||e.recurringInterval||"").toString().trim().toUpperCase():"",o=n===l.RECURRING&&"NONE"===i,c=e.appUrl||("undefined"!=typeof window&&window.location?window.location.href:void 0),u={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.hostAppDomain,merchantDomain:this.hostAppDomain,sdkVersion:m,platform:"web",appUrl:c,sessionId:this.messageHandler.getSessionId()};if(g.log("[Dropp SDK] Including SDK session context in payment params"),e.successURL&&(u.successURL=e.successURL),e.failureURL&&(u.failureURL=e.failureURL),n===l.RECURRING){const t=e.frequency||e.recurringInterval;t&&(u.frequency=t),e.recurringEndDate&&(u.expiry=e.recurringEndDate)}n===l.PREAUTH&&e.authHoldTimeInSeconds&&(u.authHoldTimeInSeconds=e.authHoldTimeInSeconds),e.callbackUrl&&(u.url=e.callbackUrl,u.submitToCallBack="post");const h={sessionId:u.sessionId,merchantAccount:this.merchantId,amount:e.amount,paymentType:n,invoiceId:u.invoiceId,expiry:e.recurringEndDate||null,issuedAt:Date.now()};let p="string"==typeof e.serverAuthToken?e.serverAuthToken.trim():"";if(!p&&this.getServerAuthToken)try{const e=await this.getServerAuthToken(h);p="string"==typeof e?e.trim():""}catch(e){throw b(d,"Failed to obtain server auth token",{originalError:e?.message||String(e)})}if(this.requireServerAuthToken&&!p)throw b(d,"serverAuthToken is required. Provide options.serverAuthToken or config.getServerAuthToken.",{environment:this.environment,paymentType:n,invoiceId:u.invoiceId});const f=await async function(e,t,n,s,i={}){try{const{serverAuthToken:o=""}=i,r={};Object.keys(n).forEach(e=>{const t=n[e];null!=t&&(r[e]=t)}),g.log("[buildPaymentUrl] Building payment URL payload");const a=w(JSON.stringify(r)),l=Date.now().toString(),c=new URLSearchParams({pay:a,sdkTs:l,sdkVersion:s,platform:"web"});return o&&c.set("authToken",o),`${e}/#${t}?${c.toString()}`}catch(e){throw g.error("Error building payment URL:",e),e}}(this.baseUrl,s,u,m,{serverAuthToken:p});g.log("[Dropp SDK] Loading payment flow iframe"),t.src=f,this.isOpen=!0,this.initTimeout=setTimeout(()=>{this._handleTimeout("init")},r),this.paymentTimeout=setTimeout(()=>{this._handleTimeout("payment")},a)}async _openHostedPage(e,t={}){if("status"===this.currentFlowType)throw b(h,"A Dropp session is already in progress",{currentSession:this.currentSession,currentFlowType:this.currentFlowType,route:e});if(this.isOpen){if("page"!==this.currentFlowType)throw b(h,"A Dropp session is already in progress",{currentSession:this.currentSession,route:e});this._cleanup()}await this.initialize(),this.currentFlowType="page",this.currentSession=null,this.onSuccess=null,this.onFailure="function"==typeof t.onFailed?t.onFailed:null,this.onCancel="function"==typeof t.onCancel?t.onCancel:null,this.onClose="function"==typeof t.onClose?t.onClose:null,this.onAccountChanged="function"==typeof t.onAccountChanged?t.onAccountChanged:null,this.onPageFailed="function"==typeof t.onPageFailed?t.onPageFailed:this.onFailure,this.messageHandler=new _(this.environment,this._handleMessage.bind(this),this.allowedOrigins),this.modalManager=new v(this._handleModalClose.bind(this));const n=this.modalManager.open();if(!n)throw new Error("Failed to create modal iframe");this.messageHandler.init(n);const s=new URLSearchParams({sdkMode:"true",sessionId:this.messageHandler.getSessionId(),sdkVersion:m,platform:"web",merchantDomain:this.hostAppDomain}),i=this._getHostedPageAuthToken();if(i&&s.set("auth",i),"/firsttimeflow"===e&&Array.isArray(t.modules)){const e=t.modules.map(e=>"string"==typeof e?e.trim():"").filter(Boolean);e.length>0&&s.set("modules",e.join(","))}const o=this.baseUrl.replace(/\/+$/,"");return n.src=`${o}/#${e}?${s.toString()}`,this.isOpen=!0,g.log("[Dropp SDK] Hosted page opened",{route:e}),{status:"opened",route:e}}_handleMessage(t){const{type:n,data:s}=t;switch(n){case e.READY:this._handleReady(s);break;case e.PAGE_LOADED:case e.PAYMENT_PAGE_LOADED:this._handlePageLoaded(s);break;case e.PAYMENT_SUCCESS:this._handleSuccess(s);break;case e.PAYMENT_FAILED:this._handleFailure(s);break;case e.PAYMENT_CANCELLED:this._handleCancel("user_cancelled");break;case e.ACCOUNT_STATUS:this._handleAccountStatus(s);break;case e.ACCOUNT_EVENT:this._handleAccountEvent(s);break;case e.PAGE_EVENT:this._handlePageEvent(s);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:if(g.log("[Dropp SDK] CLOSE_WEBVIEW received from app - closing modal"),"status"===this.currentFlowType&&this.statusSession){const e=b(p,"Account status request was closed before response was received",{type:"status",sessionDuration:Date.now()-this.statusSession.startTime});this.statusSession.reject(e),this._cleanup();break}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")}_getBridgeAction(e={}){return e&&"object"==typeof e?"string"==typeof e.action?e.action:e.result&&"object"==typeof e.result&&"string"==typeof e.result.action?e.result.action:"":""}_getSafeFailureMessage(e={},t="Request failed"){return e&&"string"==typeof e.message&&e.message.trim()?e.message.trim():e&&e.result&&"object"==typeof e.result&&"string"==typeof e.result.message&&e.result.message.trim()?e.result.message.trim():t}_getSafeResult(e={}){return e&&e.result&&"object"==typeof e.result?e.result:{}}_handleAccountEvent(e){const t=this._getBridgeAction(e),n=this._getSafeResult(e);if("onAccountChanged"!==t)if("onCancel"!==t){if("onFailed"===t){const t=this._getSafeFailureMessage(e,"Account request failed");return void(this.onFailure&&this.onFailure(t))}g.warn("[Dropp SDK] Unknown ACCOUNT_EVENT action:",t)}else this.onCancel&&this.onCancel();else this.onAccountChanged&&this.onAccountChanged({linked:!0===n.linked,rawData:n.rawData})}_handlePageEvent(e){const t=this._getBridgeAction(e);if("onFailed"===t){const t=this._getSafeFailureMessage(e,"Page request failed");return void(this.onPageFailed&&this.onPageFailed(t))}g.warn("[Dropp SDK] Unknown PAGE_EVENT action:",t)}_handleAccountStatus(t){g.log("[Dropp SDK] Account status received"),this.statusSession?(this.statusSession.resolve({type:e.ACCOUNT_STATUS,data:t}),this._cleanup()):g.warn("[Dropp SDK] ACCOUNT_STATUS received without active status session")}_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){if(g.log("[Dropp SDK] Payment cancelled"),"page"===this.currentFlowType)return this.onCancel&&this.onCancel(),void this._cleanup();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:u,"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.statusTimeout&&(clearTimeout(this.statusTimeout),this.statusTimeout=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.hiddenIframe&&this.hiddenIframe.parentNode&&this.hiddenIframe.parentNode.removeChild(this.hiddenIframe),this.hiddenIframe=null,this.currentSession=null,this.statusSession=null,this.currentFlowType=null,this.isOpen=!1,this.onClose&&this.onClose()}static getVersion(){return m}static getEnvironments(){return{...s}}static getPaymentTypes(){return{...l}}}const I="__droppDisableContextMenuListener__";!function(){if("undefined"==typeof window||"undefined"==typeof document)return;if(window[I])return;document.addEventListener("contextmenu",e=>{e.preventDefault(),e.stopPropagation()},!0),window[I]=!0}();let C=null;async function N(e){C=new A(e);return{...await C.initialize(),sdk:C}}function O(){return C}const P={init:e=>N(e),pay(e){if(!C){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 C.pay(e)},dashboard(e){if(!C){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 C.dashboard(e)},open(e,t){if(!C){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.open(moduleId, options).");throw e.code="SDK_NOT_INITIALIZED",e}return C.open(e,t)},unlinkAccount(e){if(!C){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 C.unlinkAccount(e)},transactions(e){if(!C){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 C.transactions(e)},offers(e){if(!C){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 C.offers(e)},status(){if(!C){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.status().");throw e.code="SDK_NOT_INITIALIZED",e}return C.status()},getInstance:()=>C};var k={DroppPaymentSDK:A,createPaymentSDK:N,Dropp:P,ENVIRONMENTS:s,PAYMENT_TYPES:l};export{P as Dropp,A as DroppPaymentSDK,s as ENVIRONMENTS,l as PAYMENT_TYPES,N as createPaymentSDK,k as default,O as getDroppInstance};
|
|
1
|
+
const e={READY:"DROPP_SDK_READY",PAYMENT_SUCCESS:"PAYMENT_SUCCESS",PAYMENT_FAILED:"PAYMENT_FAILED",PAYMENT_CANCELLED:"PAYMENT_CANCELLED",ACCOUNT_EVENT:"ACCOUNT_EVENT",PAGE_EVENT:"PAGE_EVENT",ACCOUNT_STATUS:"ACCOUNT_STATUS",CLOSE_WEBVIEW:"CLOSE_WEBVIEW",AUTO_CLOSE_WEBVIEW:"AUTO_CLOSE_WEBVIEW",PAYMENT_PAGE_LOADED:"PAYMENT_PAGE_LOADED",PAGE_LOADED:"PAGE_LOADED"},t="DROPP_SDK_INIT",n="DROPP_SDK_CLOSE",s={PRODUCTION:"production",QA:"qa",SANDBOX:"sandbox"},i={[s.PRODUCTION]:"https://wv.dropp.cc",[s.QA]:"https://wv.qa.dropp.cc",[s.SANDBOX]:"https://wv.sandbox.dropp.cc"},o={[s.PRODUCTION]:["https://wv.dropp.cc"],[s.QA]:["https://wv.qa.dropp.cc"],[s.SANDBOX]:["https://wv.sandbox.dropp.cc"]},r=3e4,a=6e5,l={STANDARD:"standard",PREAUTH:"preauth",RECURRING:"recurring"},c="INIT_TIMEOUT",u="PAYMENT_TIMEOUT",d="INVALID_CONFIG",p="ALREADY_OPEN",h="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],S=["item","subTotal","otherCharges","discount"],b=["label","value","type"];function w(e,t={}){const{isProduction:n=!1,allowLocalCallbacksInNonProd:s=!1}=t;if("string"!=typeof e||!e.trim())return!1;try{const t=new URL(e.trim()),i="https:"===t.protocol;if(!("http:"===t.protocol)&&!i)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[s,i]=n;return 10===s||127===s||172===s&&i>=16&&i<=31||192===s&&168===i||169===s&&254===i}(t.hostname)?!n&&s:!n||i}catch{return!1}}function T(e){return function(e){const t="string"==typeof e?e:String(e??"");if("undefined"!=typeof TextEncoder){const e=(new TextEncoder).encode(t);let n="";return e.forEach(e=>{n+=String.fromCharCode(e)}),btoa(n)}return btoa(unescape(encodeURIComponent(t)))}(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function v(e={},t={}){const n=[],s=e.paymentType||l.STANDARD,i="production"===(t.environment||"").toLowerCase(),o=!!t.allowLocalCallbacksInNonProd,r="string"==typeof e.currency?e.currency.trim().toUpperCase():"";if(D.includes(s)||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"),s===l.STANDARD){if(void 0!==e.displayItems){const t=function(e){if(!Array.isArray(e))return"displayItems must be an array of objects with keys: label, value, type";for(let t=0;t<e.length;t+=1){const n=e[t];if(!n||"object"!=typeof n||Array.isArray(n))return`displayItems[${t}] must be a valid object`;if(Object.keys(n).length!==b.length||!b.every(e=>Object.prototype.hasOwnProperty.call(n,e)))return`displayItems[${t}] must contain exactly these keys: ${b.join(", ")}`;if("string"!=typeof n.label||!n.label.trim())return`displayItems[${t}].label must be a non-empty string`;const s="number"==typeof n.value?n.value:Number(n.value);if(!Number.isFinite(s)||s<0)return`displayItems[${t}].value must be a number greater than or equal to 0`;if(!S.includes(n.type))return`displayItems[${t}].type must be one of: ${S.join(", ")}`}return null}(e.displayItems);t&&n.push(t)}void 0===e.metaData||function(e){if(!e||"object"!=typeof e||Array.isArray(e))return!1;try{return JSON.stringify(e),!0}catch{return!1}}(e.metaData)||n.push("metaData must be a valid JSON object for standard payments")}if(s===l.PREAUTH&&(r&&"USD"!==r&&n.push("currency must be USD for preauth payments"),e.callbackUrl&&String(e.callbackUrl).trim()?w(e.callbackUrl,{isProduction:i,allowLocalCallbacksInNonProd:o})||n.push(i?"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)")),s===l.RECURRING){e.callbackUrl&&String(e.callbackUrl).trim()?w(e.callbackUrl,{isProduction:i,allowLocalCallbacksInNonProd:o})||n.push(i?"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 A(e,t,n={}){return{code:e,message:t,details:n,timestamp:(new Date).toISOString(),toString(){return this.message||"Dropp SDK error"}}}class _{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.type!==e.ACCOUNT_STATUS&&!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"},s=this.allowedOrigins[0]||"*";try{return this.iframe.contentWindow.postMessage(n,s),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}}const I=["fundnow","linkbank","linkcard","redeemnow","fundcrypto","transferusdc","usdchistory","redeemcrypto","manageaccounts","transactions","merchantlist","favorites","offers","profile","pinchange","unlinkaccount","accountsettings","aboutus"];class C{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)throw new Error("merchantId and apiKey are required to initialize SDK");if(this.merchantId=e.merchantId,this.apiKey=e.apiKey,this.environment=e.environment||s.QA,this.baseUrl=e.paymentAppUrl||e.baseUrl||i[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===s.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.statusSession=null,this.hiddenIframe=null,this.statusTimeout=null,this.initTimeout=null,this.paymentTimeout=null,this.hostAppDomain=null,this.onAccountChanged=null,this.onPageFailed=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||this.currentFlowType){const e=A(p,"A payment session is already in progress",{currentSession:this.currentSession,currentFlowType:this.currentFlowType});return void n(e)}(async()=>{try{await this.initialize();const s=v(e,{environment:this.environment,allowLocalCallbacksInNonProd:this.allowLocalCallbacksInNonProd});if(!s.valid){const e=A(d,"Invalid payment configuration",{errors:s.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===d?e:A(h,"Failed to initialize payment",{originalError:e?.message||String(e)});n(t),this._cleanup()}})()})}async initialize(){return this.initializationPromise||(this.initializationPromise=(async()=>{if(this.hostAppDomain=this._detectHostAppDomain(),!this.hostAppDomain)throw A(d,"Unable to detect host app domain for SDK validation");return 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={[s.QA]:"https://bc0qfqi8c9.execute-api.us-east-1.amazonaws.com/QA-test-app-sdk-gateway-stage/sdk/payer/webview/validateSdk",[s.SANDBOX]:"https://76xbxsi4kf.execute-api.us-east-1.amazonaws.com/sandbox/sdk/payer/webview/validateSdk",[s.PRODUCTION]:"https://api.dropp.cc/payer/webview/validateSdk"};return e[this.environment]||e[s.QA]}_detectHostAppDomain(){if("undefined"!=typeof window&&window.location)return window.location.hostname||void 0}_getHostedPageAuthToken(){const e="string"==typeof this.apiKey?this.apiKey.trim():"",t="string"==typeof this.merchantId?this.merchantId.trim():"";if(!e)return"";try{return T(JSON.stringify({apikey:e,merchantAccount:t}))}catch{return""}}_formatValidationFailureMessage(e,t,n){const s=[e];Number.isFinite(t)&&s.push(`httpStatus=${t}`);const i=n?.responseCode,o=Number(i);Number.isNaN(o)||s.push(`responseCode=${o}`);let r="";if(Array.isArray(n?.errors)&&n.errors.length>0){const e=n.errors[0];r="string"==typeof e?e:e&&"string"==typeof e.message?e.message:JSON.stringify(e)}else"string"==typeof n?.message&&n.message.trim()&&(r=n.message.trim());return r&&s.push(`reason=${r}`),s.join(" | ")}async _validateInitializationCredentials(){const e=this._getValidationUrl(),t=this.hostAppDomain;if(!t)throw A(d,"Unable to resolve host app domain for SDK validation");const n={accept:"application/json, text/plain, */*","content-type":"application/json","x-api-key":this.apiKey,"x-app-package":t,"dropp-user-agent":"WEB"};let s;n["dropp-merchant-domain"]=t;let i=null;try{s=await fetch(e,{method:"POST",headers:n,body:JSON.stringify({id:this.merchantId})})}catch(t){throw A(d,"Unable to validate merchant credentials",{endpoint:e,originalError:t?.message||String(t)})}try{i=await s.json()}catch{i=null}if(!s.ok){const t=this._formatValidationFailureMessage("Merchant validation failed for merchantId/apiKey/domain",s.status,i);throw A(d,t,{endpoint:e,status:s.status,response:i})}const o=Number(i?.responseCode),r=i?.errors,a=!Array.isArray(r)||0===r.length;if(!(i&&0===o&&a)){const t=this._formatValidationFailureMessage("Merchant validation returned an unsuccessful response",s.status,i);throw A(d,t,{endpoint:e,status:s.status,response:i})}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)}open(e,t={}){const n="string"==typeof e?e.trim():"";if(!n)throw A(d,"moduleId is required for Dropp.open(moduleId)",{moduleId:e});if(!I.includes(n))throw A(d,"Unsupported moduleId passed to Dropp.open(moduleId)",{moduleId:n,supportedModuleIds:[...I]});const s="about"===n?"/aboutus":`/${n}`;return this._openHostedPage(s,t)}unlinkAccount(e={}){return this._openHostedPage("/unlink",e)}transactions(e={}){return this._openHostedPage("/transactions",e)}offers(e={}){return this._openHostedPage("/offers",e)}status(){return new Promise((e,t)=>{this.isOpen||this.currentFlowType?t(A(p,"A Dropp session is already in progress",{currentSession:this.currentSession,currentFlowType:this.currentFlowType})):(async()=>{try{this.currentFlowType="status",await this.initialize(),this.currentSession=null,this.onSuccess=null,this.onFailure=null,this.onCancel=null,this.onClose=null,this.messageHandler=new _(this.environment,this._handleMessage.bind(this),this.allowedOrigins);const n=document.createElement("iframe");n.id="dropp-status-iframe",n.setAttribute("allow","payment"),n.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),n.setAttribute("referrerpolicy","no-referrer"),n.setAttribute("title","Dropp Account Status"),Object.assign(n.style,{position:"absolute",width:"1px",height:"1px",border:"0",opacity:"0",pointerEvents:"none",visibility:"hidden"}),document.body.appendChild(n),this.hiddenIframe=n,this.messageHandler.init(n);const s=new URLSearchParams({sdkMode:"true",sessionId:this.messageHandler.getSessionId(),sdkVersion:m,platform:"web",merchantDomain:this.hostAppDomain}),i=this._getHostedPageAuthToken();i&&s.set("auth",i);const o=this.baseUrl.replace(/\/+$/,"");n.src=`${o}/#/status?${s.toString()}`,this.statusSession={resolve:e,reject:t,startTime:Date.now()},this.statusTimeout=setTimeout(()=>{const e=A(c,"Account status request timed out",{type:"status",sessionDuration:this.statusSession?Date.now()-this.statusSession.startTime:0});this.statusSession&&this.statusSession.reject(e),this._cleanup()},r)}catch(e){t(A(h,"Failed to get account status",{originalError:e?.message||String(e)})),this._cleanup()}})()})}async _initializePayment(e){g.log("[Dropp SDK] Initializing payment session"),this.currentFlowType="payment",this.messageHandler=new _(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 s="/payViaUrl";n===l.PREAUTH?s="/preAuthPayment":n===l.RECURRING&&(s="/recurringPayment");const i=n===l.RECURRING?(e.frequency||e.recurringInterval||"").toString().trim().toUpperCase():"",o=n===l.RECURRING&&"NONE"===i,c=e.appUrl||("undefined"!=typeof window&&window.location?window.location.href:void 0),u={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.hostAppDomain,merchantDomain:this.hostAppDomain,sdkVersion:m,platform:"web",appUrl:c,sessionId:this.messageHandler.getSessionId()};if(n===l.STANDARD&&(void 0!==e.displayItems&&(u.displayItems=e.displayItems),void 0!==e.metaData&&(u.metaData=e.metaData)),g.log("[Dropp SDK] Including SDK session context in payment params"),e.successURL&&(u.successURL=e.successURL),e.failureURL&&(u.failureURL=e.failureURL),n===l.RECURRING){const t=e.frequency||e.recurringInterval;t&&(u.frequency=t),e.recurringEndDate&&(u.expiry=e.recurringEndDate)}n===l.PREAUTH&&e.authHoldTimeInSeconds&&(u.authHoldTimeInSeconds=e.authHoldTimeInSeconds),e.callbackUrl&&(u.url=e.callbackUrl,u.submitToCallBack="post");const p={sessionId:u.sessionId,merchantAccount:this.merchantId,amount:e.amount,paymentType:n,invoiceId:u.invoiceId,expiry:e.recurringEndDate||null,issuedAt:Date.now()};let h="string"==typeof e.serverAuthToken?e.serverAuthToken.trim():"";if(!h&&this.getServerAuthToken)try{const e=await this.getServerAuthToken(p);h="string"==typeof e?e.trim():""}catch(e){throw A(d,"Failed to obtain server auth token",{originalError:e?.message||String(e)})}if(this.requireServerAuthToken&&!h)throw A(d,"serverAuthToken is required. Provide options.serverAuthToken or config.getServerAuthToken.",{environment:this.environment,paymentType:n,invoiceId:u.invoiceId});const y=await async function(e,t,n,s,i={}){try{const{serverAuthToken:o=""}=i,r={};Object.keys(n).forEach(e=>{const t=n[e];null!=t&&(r[e]=t)}),g.log("[buildPaymentUrl] Building payment URL payload");const a=T(JSON.stringify(r)),l=Date.now().toString(),c=new URLSearchParams({pay:a,sdkTs:l,sdkVersion:s,platform:"web"});return o&&c.set("authToken",o),`${e}/#${t}?${c.toString()}`}catch(e){throw g.error("Error building payment URL:",e),e}}(this.baseUrl,s,u,m,{serverAuthToken:h});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("status"===this.currentFlowType)throw A(p,"A Dropp session is already in progress",{currentSession:this.currentSession,currentFlowType:this.currentFlowType,route:e});if(this.isOpen){if("page"!==this.currentFlowType)throw A(p,"A Dropp session is already in progress",{currentSession:this.currentSession,route:e});this._cleanup()}await this.initialize(),this.currentFlowType="page",this.currentSession=null,this.onSuccess=null,this.onFailure="function"==typeof t.onFailed?t.onFailed:null,this.onCancel="function"==typeof t.onCancel?t.onCancel:null,this.onClose="function"==typeof t.onClose?t.onClose:null,this.onAccountChanged="function"==typeof t.onAccountChanged?t.onAccountChanged:null,this.onPageFailed="function"==typeof t.onPageFailed?t.onPageFailed:this.onFailure,this.messageHandler=new _(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 s=new URLSearchParams({sdkMode:"true",sessionId:this.messageHandler.getSessionId(),sdkVersion:m,platform:"web",merchantDomain:this.hostAppDomain}),i=this._getHostedPageAuthToken();if(i&&s.set("auth",i),"/firsttimeflow"===e&&Array.isArray(t.modules)){const e=t.modules.map(e=>"string"==typeof e?e.trim():"").filter(Boolean);e.length>0&&s.set("modules",e.join(","))}const o=this.baseUrl.replace(/\/+$/,"");return n.src=`${o}/#${e}?${s.toString()}`,this.isOpen=!0,g.log("[Dropp SDK] Hosted page opened",{route:e}),{status:"opened",route:e}}_handleMessage(t){const{type:n,data:s}=t;switch(n){case e.READY:this._handleReady(s);break;case e.PAGE_LOADED:case e.PAYMENT_PAGE_LOADED:this._handlePageLoaded(s);break;case e.PAYMENT_SUCCESS:this._handleSuccess(s);break;case e.PAYMENT_FAILED:this._handleFailure(s);break;case e.PAYMENT_CANCELLED:this._handleCancel("user_cancelled");break;case e.ACCOUNT_STATUS:this._handleAccountStatus(s);break;case e.ACCOUNT_EVENT:this._handleAccountEvent(s);break;case e.PAGE_EVENT:this._handlePageEvent(s);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:if(g.log("[Dropp SDK] CLOSE_WEBVIEW received from app - closing modal"),"status"===this.currentFlowType&&this.statusSession){const e=A(h,"Account status request was closed before response was received",{type:"status",sessionDuration:Date.now()-this.statusSession.startTime});this.statusSession.reject(e),this._cleanup();break}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")}_getBridgeAction(e={}){return e&&"object"==typeof e?"string"==typeof e.action?e.action:e.result&&"object"==typeof e.result&&"string"==typeof e.result.action?e.result.action:"":""}_getSafeFailureMessage(e={},t="Request failed"){return e&&"string"==typeof e.message&&e.message.trim()?e.message.trim():e&&e.result&&"object"==typeof e.result&&"string"==typeof e.result.message&&e.result.message.trim()?e.result.message.trim():t}_getSafeResult(e={}){return e&&e.result&&"object"==typeof e.result?e.result:{}}_handleAccountEvent(e){const t=this._getBridgeAction(e),n=this._getSafeResult(e);if("onAccountChanged"!==t)if("onCancel"!==t){if("onFailed"===t){const t=this._getSafeFailureMessage(e,"Account request failed");return void(this.onFailure&&this.onFailure(t))}g.warn("[Dropp SDK] Unknown ACCOUNT_EVENT action:",t)}else this.onCancel&&this.onCancel();else this.onAccountChanged&&this.onAccountChanged({linked:!0===n.linked,rawData:n.rawData})}_handlePageEvent(e){const t=this._getBridgeAction(e);if("onFailed"===t){const t=this._getSafeFailureMessage(e,"Page request failed");return void(this.onPageFailed&&this.onPageFailed(t))}g.warn("[Dropp SDK] Unknown PAGE_EVENT action:",t)}_handleAccountStatus(t){g.log("[Dropp SDK] Account status received"),this.statusSession?(this.statusSession.resolve({type:e.ACCOUNT_STATUS,data:t}),this._cleanup()):g.warn("[Dropp SDK] ACCOUNT_STATUS received without active status session")}_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){if(g.log("[Dropp SDK] Payment cancelled"),"page"===this.currentFlowType)return this.onCancel&&this.onCancel(),void this._cleanup();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=A("init"===e?c:u,"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.statusTimeout&&(clearTimeout(this.statusTimeout),this.statusTimeout=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.hiddenIframe&&this.hiddenIframe.parentNode&&this.hiddenIframe.parentNode.removeChild(this.hiddenIframe),this.hiddenIframe=null,this.currentSession=null,this.statusSession=null,this.currentFlowType=null,this.isOpen=!1,this.onClose&&this.onClose()}static getVersion(){return m}static getEnvironments(){return{...s}}static getPaymentTypes(){return{...l}}}const N="__droppDisableContextMenuListener__";!function(){if("undefined"==typeof window||"undefined"==typeof document)return;if(window[N])return;document.addEventListener("contextmenu",e=>{e.preventDefault(),e.stopPropagation()},!0),window[N]=!0}();let O=null;async function P(e){O=new C(e);return{...await O.initialize(),sdk:O}}function k(){return O}const M={init:e=>P(e),pay(e){if(!O){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 O.pay(e)},dashboard(e){if(!O){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 O.dashboard(e)},open(e,t){if(!O){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.open(moduleId, options).");throw e.code="SDK_NOT_INITIALIZED",e}return O.open(e,t)},unlinkAccount(e){if(!O){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 O.unlinkAccount(e)},transactions(e){if(!O){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 O.transactions(e)},offers(e){if(!O){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 O.offers(e)},status(){if(!O){const e=new Error("Dropp SDK is not initialized. Call Dropp.init(config) before Dropp.status().");throw e.code="SDK_NOT_INITIALIZED",e}return O.status()},getInstance:()=>O};var U={DroppPaymentSDK:C,createPaymentSDK:P,Dropp:M,ENVIRONMENTS:s,PAYMENT_TYPES:l};export{M as Dropp,C as DroppPaymentSDK,s as ENVIRONMENTS,l as PAYMENT_TYPES,P as createPaymentSDK,U as default,k as getDroppInstance};
|
|
2
2
|
//# sourceMappingURL=dropp-payment-sdk.esm.js.map
|