@glomopay/react-native-sdk 2.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/MIGRATION.md +50 -0
  3. package/README.md +348 -316
  4. package/lib/config/base.d.ts +17 -11
  5. package/lib/config/base.d.ts.map +1 -1
  6. package/lib/config/base.js +19 -7
  7. package/lib/config/segment.js +3 -3
  8. package/lib/glomo-checkout.d.ts +8 -0
  9. package/lib/glomo-checkout.d.ts.map +1 -0
  10. package/lib/glomo-checkout.js +106 -0
  11. package/lib/glomo-lrs-checkout.js +9 -9
  12. package/lib/glomo-standard-checkout.d.ts +25 -0
  13. package/lib/glomo-standard-checkout.d.ts.map +1 -0
  14. package/lib/glomo-standard-checkout.js +229 -0
  15. package/lib/glomo-subscriptions-checkout.d.ts +8 -0
  16. package/lib/glomo-subscriptions-checkout.d.ts.map +1 -0
  17. package/lib/glomo-subscriptions-checkout.js +85 -0
  18. package/lib/index.d.ts +5 -4
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +7 -5
  21. package/lib/injections/index.d.ts +1 -0
  22. package/lib/injections/index.d.ts.map +1 -1
  23. package/lib/injections/index.js +2 -0
  24. package/lib/injections/webview-flow.injection.d.ts.map +1 -1
  25. package/lib/injections/webview-flow.injection.js +106 -69
  26. package/lib/injections/webview-main.injection.d.ts.map +1 -1
  27. package/lib/injections/webview-main.injection.js +112 -77
  28. package/lib/injections/webview-standard.injection.d.ts +3 -0
  29. package/lib/injections/webview-standard.injection.d.ts.map +1 -0
  30. package/lib/injections/webview-standard.injection.js +214 -0
  31. package/lib/services/order-type-fetcher.d.ts +28 -0
  32. package/lib/services/order-type-fetcher.d.ts.map +1 -0
  33. package/lib/services/order-type-fetcher.js +99 -0
  34. package/lib/types/checkout.d.ts +65 -0
  35. package/lib/types/checkout.d.ts.map +1 -0
  36. package/lib/types/checkout.js +3 -0
  37. package/lib/types/standard-checkout.d.ts +40 -0
  38. package/lib/types/standard-checkout.d.ts.map +1 -0
  39. package/lib/types/standard-checkout.js +3 -0
  40. package/lib/types/subscriptions-checkout.d.ts +29 -0
  41. package/lib/types/subscriptions-checkout.d.ts.map +1 -0
  42. package/lib/types/subscriptions-checkout.js +3 -0
  43. package/lib/use-glomo-checkout.d.ts +54 -0
  44. package/lib/use-glomo-checkout.d.ts.map +1 -0
  45. package/lib/use-glomo-checkout.js +261 -0
  46. package/lib/use-lrs-checkout.d.ts +9 -4
  47. package/lib/use-lrs-checkout.d.ts.map +1 -1
  48. package/lib/use-lrs-checkout.js +76 -93
  49. package/lib/use-standard-checkout.d.ts +74 -0
  50. package/lib/use-standard-checkout.d.ts.map +1 -0
  51. package/lib/use-standard-checkout.js +849 -0
  52. package/lib/utils/analytics.d.ts +188 -2
  53. package/lib/utils/analytics.d.ts.map +1 -1
  54. package/lib/utils/analytics.js +636 -22
  55. package/lib/utils/device-compliance.d.ts.map +1 -1
  56. package/lib/utils/device-compliance.js +3 -4
  57. package/lib/utils/validation.d.ts.map +1 -1
  58. package/lib/utils/validation.js +7 -6
  59. package/package.json +17 -5
  60. package/src/config/base.ts +36 -17
  61. package/src/config/segment.ts +3 -3
  62. package/src/glomo-checkout.tsx +147 -0
  63. package/src/glomo-lrs-checkout.tsx +9 -9
  64. package/src/glomo-standard-checkout.tsx +353 -0
  65. package/src/glomo-subscriptions-checkout.tsx +83 -0
  66. package/src/index.ts +13 -7
  67. package/src/injections/index.ts +2 -0
  68. package/src/injections/webview-flow.injection.ts +106 -69
  69. package/src/injections/webview-main.injection.ts +112 -77
  70. package/src/injections/webview-standard.injection.ts +211 -0
  71. package/src/services/order-type-fetcher.ts +86 -0
  72. package/src/types/checkout.ts +72 -0
  73. package/src/types/standard-checkout.ts +49 -0
  74. package/src/types/subscriptions-checkout.ts +31 -0
  75. package/src/use-glomo-checkout.tsx +369 -0
  76. package/src/use-lrs-checkout.tsx +91 -111
  77. package/src/use-standard-checkout.tsx +1203 -0
  78. package/src/utils/analytics.ts +908 -34
  79. package/src/utils/device-compliance.ts +3 -4
  80. package/src/utils/validation.ts +7 -8
@@ -18,7 +18,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
18
18
  const educationCarouselWebViewRef = (0, react_1.useRef)(null);
19
19
  // Resolving checkout and carousel URLs from the selected SDK server
20
20
  const serverConfig = (0, react_1.useMemo)(() => (0, base_1.resolveServerConfig)(server), [server]);
21
- const baseCheckoutUrl = serverConfig.checkoutBaseUrl;
21
+ const baseCheckoutUrl = serverConfig.baseUrl.lrsCheckout;
22
22
  /**
23
23
  * The main checkout URL for the LRS flow
24
24
  * In future, this needs to come from the LRS Checkout SDK.
@@ -36,80 +36,50 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
36
36
  // Validating the final URL
37
37
  if (!(0, validation_1.isValidUrl)(finalUrl)) {
38
38
  if (devMode) {
39
- console.error("[GlomoPay RN SDK] Generated invalid checkout URL:", finalUrl);
39
+ console.error("[Glomo-RN-SDK LRS] Generated invalid checkout URL:", finalUrl);
40
40
  }
41
- const errors = [
42
- {
43
- type: "validation_error",
44
- message: "Generated invalid checkout URL",
45
- },
46
- ];
47
- (0, validation_1.safeCallback)(onSdkError, [errors], "onSdkError", devMode);
48
- (0, analytics_1.trackSdkError)(errors, orderId, publicKey, devMode, mockMode, finalUrl ? finalUrl : finalUrl === null ? "null" : "undefined");
49
41
  return "";
50
42
  }
51
43
  if (devMode) {
52
- console.log("[GlomoPay RN SDK] Checkout URL:", finalUrl);
44
+ console.log("[Glomo-RN-SDK LRS] Checkout URL:", finalUrl);
53
45
  }
54
46
  return finalUrl;
55
47
  }
56
48
  catch (error) {
57
49
  if (devMode) {
58
- console.error("[GlomoPay RN SDK] Error building checkout URL:", error);
50
+ console.error("[Glomo-RN-SDK LRS] Error building checkout URL:", error);
59
51
  }
60
- const errors = [
61
- {
62
- type: "validation_error",
63
- message: `Error building checkout URL: ${error instanceof Error ? error.message : "Unknown error"}`,
64
- },
65
- ];
66
- (0, validation_1.safeCallback)(onSdkError, [errors], "onSdkError", devMode);
67
- (0, analytics_1.trackSdkError)(errors, orderId, publicKey, devMode, mockMode, "");
68
52
  return "";
69
53
  }
70
- }, [baseCheckoutUrl, orderId, publicKey, mockMode, devMode, onSdkError]);
54
+ }, [baseCheckoutUrl, orderId, publicKey, mockMode, devMode]);
71
55
  /**
72
56
  * The education carousel URL, built from the server config with the current orderId and publicKey.
73
57
  * Loaded in a hidden WebView alongside the flow WebView; shown only once the carousel signals it has content.
74
58
  */
75
59
  const educationCarouselUrl = (0, react_1.useMemo)(() => {
76
60
  try {
77
- const baseEducationCarouselUrl = serverConfig.educationCarouselBaseUrl;
61
+ const baseEducationCarouselUrl = serverConfig.baseUrl.lrsEducationCarousel;
78
62
  const separator = baseEducationCarouselUrl.includes("?") ? "&" : "?";
79
63
  const finalUrl = `${baseEducationCarouselUrl}${separator}orderId=${encodeURIComponent(orderId)}` +
80
64
  `&publicKey=${encodeURIComponent(publicKey)}`;
81
65
  if (!(0, validation_1.isValidUrl)(finalUrl)) {
82
66
  if (devMode) {
83
- console.error("[GlomoPay RN SDK] Generated invalid education carousel URL:", finalUrl);
67
+ console.error("[Glomo-RN-SDK LRS] Generated invalid education carousel URL:", finalUrl);
84
68
  }
85
- const errors = [
86
- {
87
- type: "validation_error",
88
- message: "Generated invalid education carousel URL",
89
- },
90
- ];
91
- (0, analytics_1.trackSdkError)(errors, orderId, publicKey, devMode, mockMode, finalUrl ? finalUrl : finalUrl === null ? "null" : "undefined");
92
69
  return "";
93
70
  }
94
71
  if (devMode) {
95
- console.log("[GlomoPay RN SDK] Education Carousel URL:", finalUrl);
72
+ console.log("[Glomo-RN-SDK LRS] Education Carousel URL:", finalUrl);
96
73
  }
97
74
  return finalUrl;
98
75
  }
99
76
  catch (error) {
100
77
  if (devMode) {
101
- console.error("[GlomoPay RN SDK] Error building education carousel URL:", error);
78
+ console.error("[Glomo-RN-SDK LRS] Error building education carousel URL:", error);
102
79
  }
103
- const errors = [
104
- {
105
- type: "validation_error",
106
- message: `Error building education carousel URL: ${error instanceof Error ? error.message : "Unknown error"}`,
107
- },
108
- ];
109
- (0, analytics_1.trackSdkError)(errors, orderId, publicKey, devMode, mockMode, "");
110
80
  return "";
111
81
  }
112
- }, [serverConfig, orderId, publicKey, devMode, mockMode]);
82
+ }, [serverConfig, orderId, publicKey, devMode]);
113
83
  // Checkout status state
114
84
  const [status, setStatus] = (0, react_1.useState)("ready");
115
85
  // Visibility state for the main checkout modal
@@ -119,9 +89,15 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
119
89
  const [educationCarouselState, setEducationCarouselState] = (0, react_1.useState)("pending");
120
90
  (0, react_1.useEffect)(() => {
121
91
  if (devMode) {
122
- console.log(`[GlomoPay RN SDK] Carousel state snapshot: status=${status}, showCheckout=${showCheckout}, showFlowWebView=${showFlowWebView}, flowWebViewUrl=${flowWebViewUrl || "<empty>"}, educationCarouselState=${educationCarouselState}, educationCarouselUrl=${educationCarouselUrl || "<empty>"}`);
92
+ console.log(`[Glomo-RN-SDK LRS] Carousel state snapshot: status=${status}, showCheckout=${showCheckout}, showFlowWebView=${showFlowWebView}, flowWebViewUrl=${flowWebViewUrl || "<empty>"}, educationCarouselState=${educationCarouselState}, educationCarouselUrl=${educationCarouselUrl || "<empty>"}`);
123
93
  }
124
94
  }, [devMode, status, showCheckout, showFlowWebView, flowWebViewUrl, educationCarouselState, educationCarouselUrl]);
95
+ // Tracking when the education carousel URL is invalid (empty) despite having valid orderId and publicKey
96
+ (0, react_1.useEffect)(() => {
97
+ if (orderId && publicKey && !educationCarouselUrl) {
98
+ (0, analytics_1.trackEducationStepsFailedToShow)(orderId, publicKey, devMode, mockMode, checkoutUrl, "invalid_url");
99
+ }
100
+ }, [educationCarouselUrl, orderId, publicKey, devMode, mockMode, checkoutUrl]);
125
101
  // Handler for the WebView errors
126
102
  const handleError = (0, react_1.useCallback)((syntheticEvent) => {
127
103
  try {
@@ -144,7 +120,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
144
120
  description.includes("ERR_NETWORK_CHANGED")); // Network changed
145
121
  if (isIOSConnectionError || isAndroidConnectionError) {
146
122
  if (devMode) {
147
- console.error("[GlomoPay RN SDK] Connection error:", nativeEvent);
123
+ console.error("[Glomo-RN-SDK LRS] Connection error:", nativeEvent);
148
124
  }
149
125
  // Closing the checkout modal
150
126
  setShowCheckout(false);
@@ -158,13 +134,13 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
158
134
  }
159
135
  else {
160
136
  if (devMode) {
161
- console.error("[GlomoPay RN SDK] WebView error:", nativeEvent);
137
+ console.error("[Glomo-RN-SDK LRS] WebView error:", nativeEvent);
162
138
  }
163
139
  }
164
140
  }
165
141
  catch (error) {
166
142
  if (devMode) {
167
- console.error("[GlomoPay RN SDK] Error in handleError:", error);
143
+ console.error("[Glomo-RN-SDK LRS] Error in handleError:", error);
168
144
  }
169
145
  }
170
146
  }, [devMode, onConnectionError, checkoutUrl, orderId, publicKey, mockMode]);
@@ -173,12 +149,12 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
173
149
  try {
174
150
  const { nativeEvent } = syntheticEvent;
175
151
  if (devMode) {
176
- console.error("[GlomoPay RN SDK] WebView HTTP error:", nativeEvent);
152
+ console.error("[Glomo-RN-SDK LRS] WebView HTTP error:", nativeEvent);
177
153
  }
178
154
  }
179
155
  catch (error) {
180
156
  if (devMode) {
181
- console.error("[GlomoPay RN SDK] Error in handleHttpError:", error);
157
+ console.error("[Glomo-RN-SDK LRS] Error in handleHttpError:", error);
182
158
  }
183
159
  }
184
160
  }, [devMode]);
@@ -189,7 +165,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
189
165
  const data = (_a = event.nativeEvent) === null || _a === void 0 ? void 0 : _a.data;
190
166
  if (!data || typeof data !== "string") {
191
167
  if (devMode) {
192
- console.warn("[GlomoPay RN SDK] Invalid message data from MainWebView");
168
+ console.warn("[Glomo-RN-SDK LRS] Invalid message data from MainWebView");
193
169
  }
194
170
  // Tracking invalid message received
195
171
  (0, analytics_1.trackInvalidMessageReceived)("main", data, checkoutUrl, orderId, publicKey, devMode, mockMode, checkoutUrl);
@@ -197,12 +173,12 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
197
173
  }
198
174
  const message = JSON.parse(data);
199
175
  if (devMode) {
200
- console.log("[GlomoPay RN SDK] MainWebView Message received:", message.type, message);
176
+ console.log("[Glomo-RN-SDK LRS] MainWebView Message received:", message.type, message);
201
177
  }
202
178
  if (message.type === "console") {
203
179
  if (devMode) {
204
180
  const level = message.level || "log";
205
- console.log(`[GlomoPay RN SDK] [WebView ${level.toUpperCase()}]`, message.message);
181
+ console.log(`[Glomo-RN-SDK LRS] [WebView ${level.toUpperCase()}]`, message.message);
206
182
  }
207
183
  return;
208
184
  }
@@ -210,7 +186,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
210
186
  const url = message.url;
211
187
  if (url && typeof url === "string" && (0, validation_1.isValidUrl)(url)) {
212
188
  if (devMode) {
213
- console.log(`[GlomoPay RN SDK] window.open called from MainWebView: ${url}`);
189
+ console.log(`[Glomo-RN-SDK LRS] window.open called from MainWebView: ${url}`);
214
190
  }
215
191
  setFlowWebViewUrl(url);
216
192
  setShowFlowWebView(true);
@@ -220,14 +196,14 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
220
196
  }
221
197
  else {
222
198
  if (devMode) {
223
- console.log("[GlomoPay RN SDK] Invalid URL in window.open from MainWebView:", url, typeof url === "undefined" ? "undefined" : "");
199
+ console.log("[Glomo-RN-SDK LRS] Invalid URL in window.open from MainWebView:", url, typeof url === "undefined" ? "undefined" : "");
224
200
  }
225
201
  }
226
202
  return;
227
203
  }
228
204
  if (message.type === "window.close") {
229
205
  if (devMode) {
230
- console.log("[GlomoPay RN SDK] Child window close requested from MainWebView");
206
+ console.log("[Glomo-RN-SDK LRS] Child window close requested from MainWebView");
231
207
  }
232
208
  setShowFlowWebView(false);
233
209
  setFlowWebViewUrl("");
@@ -245,7 +221,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
245
221
  const payload = paymentMessage === null || paymentMessage === void 0 ? void 0 : paymentMessage.payload;
246
222
  if ((0, validation_1.isValidPaymentPayload)(payload)) {
247
223
  if (devMode) {
248
- console.log("[GlomoPay RN SDK] Payment successful via merchant callback!");
224
+ console.log("[Glomo-RN-SDK LRS] Payment successful via merchant callback!");
249
225
  }
250
226
  setShowCheckout(false);
251
227
  setShowFlowWebView(false);
@@ -258,7 +234,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
258
234
  }
259
235
  else {
260
236
  if (devMode) {
261
- console.error("[GlomoPay RN SDK] Invalid payment success payload:", payload);
237
+ console.error("[Glomo-RN-SDK LRS] Invalid payment success payload:", payload);
262
238
  }
263
239
  }
264
240
  return;
@@ -268,7 +244,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
268
244
  const payload = paymentMessage === null || paymentMessage === void 0 ? void 0 : paymentMessage.payload;
269
245
  if ((0, validation_1.isValidPaymentPayload)(payload)) {
270
246
  if (devMode) {
271
- console.error("[GlomoPay RN SDK] Payment failed via merchant callback");
247
+ console.error("[Glomo-RN-SDK LRS] Payment failed via merchant callback");
272
248
  }
273
249
  setShowCheckout(false);
274
250
  setShowFlowWebView(false);
@@ -281,7 +257,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
281
257
  }
282
258
  else {
283
259
  if (devMode) {
284
- console.error("[GlomoPay RN SDK] Invalid payment failure payload:", payload);
260
+ console.error("[Glomo-RN-SDK LRS] Invalid payment failure payload:", payload);
285
261
  }
286
262
  }
287
263
  return;
@@ -289,7 +265,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
289
265
  // Handling checkout.closed events
290
266
  if (messageType === "checkout.closed") {
291
267
  if (devMode) {
292
- console.log("[GlomoPay RN SDK] Checkout closed event received");
268
+ console.log("[Glomo-RN-SDK LRS] Checkout closed event received");
293
269
  }
294
270
  setShowCheckout(false);
295
271
  setShowFlowWebView(false);
@@ -304,7 +280,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
304
280
  }
305
281
  catch (error) {
306
282
  if (devMode) {
307
- console.error("[GlomoPay RN SDK] Error parsing MainWebView message:", error);
283
+ console.error("[Glomo-RN-SDK LRS] Error parsing MainWebView message:", error);
308
284
  }
309
285
  }
310
286
  }, [onPaymentSuccess, onPaymentFailure, onPaymentTerminate, devMode, mockMode, orderId, publicKey, checkoutUrl]);
@@ -315,7 +291,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
315
291
  const data = (_a = event.nativeEvent) === null || _a === void 0 ? void 0 : _a.data;
316
292
  if (!data || typeof data !== "string") {
317
293
  if (devMode) {
318
- console.warn("[GlomoPay RN SDK] Invalid message data from FlowWebView");
294
+ console.warn("[Glomo-RN-SDK LRS] Invalid message data from FlowWebView");
319
295
  }
320
296
  // Tracking invalid message received
321
297
  (0, analytics_1.trackInvalidMessageReceived)("flow", data, flowWebViewUrl, orderId, publicKey, devMode, mockMode, checkoutUrl);
@@ -323,11 +299,11 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
323
299
  }
324
300
  const message = JSON.parse(data);
325
301
  if (devMode) {
326
- console.log("[GlomoPay RN SDK] FlowWebView Message received:", message.type, message);
302
+ console.log("[Glomo-RN-SDK LRS] FlowWebView Message received:", message.type, message);
327
303
  }
328
304
  if (message.type === "console") {
329
305
  if (devMode) {
330
- console.log(`[GlomoPay RN SDK] [Flow] ${message.message}`);
306
+ console.log(`[Glomo-RN-SDK LRS] [Flow] ${message.message}`);
331
307
  }
332
308
  return;
333
309
  }
@@ -335,7 +311,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
335
311
  const url = message.url;
336
312
  if (url && typeof url === "string" && (0, validation_1.isValidUrl)(url)) {
337
313
  if (devMode) {
338
- console.log(`[GlomoPay RN SDK] window.open called from FlowWebView: ${url}`);
314
+ console.log(`[Glomo-RN-SDK LRS] window.open called from FlowWebView: ${url}`);
339
315
  }
340
316
  setFlowWebViewUrl(url);
341
317
  setEducationCarouselState("pending");
@@ -344,14 +320,14 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
344
320
  }
345
321
  else {
346
322
  if (devMode) {
347
- console.log("[GlomoPay RN SDK] Invalid URL in window.open from FlowWebView:", url, typeof url === "undefined" ? "undefined" : "");
323
+ console.log("[Glomo-RN-SDK LRS] Invalid URL in window.open from FlowWebView:", url, typeof url === "undefined" ? "undefined" : "");
348
324
  }
349
325
  }
350
326
  return;
351
327
  }
352
328
  if (message.type === "window.close") {
353
329
  if (devMode) {
354
- console.log("[GlomoPay RN SDK] FlowWebView close requested");
330
+ console.log("[Glomo-RN-SDK LRS] FlowWebView close requested");
355
331
  }
356
332
  setShowFlowWebView(false);
357
333
  setFlowWebViewUrl("");
@@ -368,7 +344,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
368
344
  const payload = paymentMessage === null || paymentMessage === void 0 ? void 0 : paymentMessage.payload;
369
345
  if ((0, validation_1.isValidPaymentPayload)(payload)) {
370
346
  if (devMode) {
371
- console.log("[GlomoPay RN SDK] Payment successful via FlowWebView callback!");
347
+ console.log("[Glomo-RN-SDK LRS] Payment successful via FlowWebView callback!");
372
348
  }
373
349
  setShowFlowWebView(false);
374
350
  setShowCheckout(false);
@@ -381,7 +357,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
381
357
  }
382
358
  else {
383
359
  if (devMode) {
384
- console.error("[GlomoPay RN SDK] Invalid payment success payload from FlowWebView:", payload);
360
+ console.error("[Glomo-RN-SDK LRS] Invalid payment success payload from FlowWebView:", payload);
385
361
  }
386
362
  }
387
363
  return;
@@ -391,7 +367,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
391
367
  const payload = paymentMessage === null || paymentMessage === void 0 ? void 0 : paymentMessage.payload;
392
368
  if ((0, validation_1.isValidPaymentPayload)(payload)) {
393
369
  if (devMode) {
394
- console.error("[GlomoPay RN SDK] Payment failed via FlowWebView callback");
370
+ console.error("[Glomo-RN-SDK LRS] Payment failed via FlowWebView callback");
395
371
  }
396
372
  setShowFlowWebView(false);
397
373
  setShowCheckout(false);
@@ -404,7 +380,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
404
380
  }
405
381
  else {
406
382
  if (devMode) {
407
- console.error("[GlomoPay RN SDK] Invalid payment failure payload from FlowWebView:", payload);
383
+ console.error("[Glomo-RN-SDK LRS] Invalid payment failure payload from FlowWebView:", payload);
408
384
  }
409
385
  }
410
386
  return;
@@ -413,7 +389,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
413
389
  }
414
390
  catch (error) {
415
391
  if (devMode) {
416
- console.error("[GlomoPay RN SDK] Error parsing FlowWebView message:", error);
392
+ console.error("[Glomo-RN-SDK LRS] Error parsing FlowWebView message:", error);
417
393
  }
418
394
  }
419
395
  }, [onPaymentSuccess, onPaymentFailure, devMode, mockMode, orderId, publicKey, flowWebViewUrl, checkoutUrl]);
@@ -424,24 +400,24 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
424
400
  const data = (_a = event.nativeEvent) === null || _a === void 0 ? void 0 : _a.data;
425
401
  if (!data || typeof data !== "string") {
426
402
  if (devMode) {
427
- console.warn("[GlomoPay RN SDK] Invalid message data from EducationCarouselWebView");
403
+ console.warn("[Glomo-RN-SDK LRS] Invalid message data from EducationCarouselWebView");
428
404
  }
429
405
  return;
430
406
  }
431
407
  const message = JSON.parse(data);
432
408
  if (devMode) {
433
- console.log("[GlomoPay RN SDK] EducationCarouselWebView Message received:", message.type, message);
409
+ console.log("[Glomo-RN-SDK LRS] EducationCarouselWebView Message received:", message.type, message);
434
410
  }
435
411
  if (message.type === "console") {
436
412
  if (devMode) {
437
- console.log(`[GlomoPay RN SDK] [EducationCarousel] ${message.message}`);
413
+ console.log(`[Glomo-RN-SDK LRS] [EducationCarousel] ${message.message}`);
438
414
  }
439
415
  return;
440
416
  }
441
417
  if (message.type === "lrs.has_education_steps") {
442
418
  const nextState = "hasContent";
443
419
  if (devMode) {
444
- console.log(`[GlomoPay RN SDK] Education carousel signal received: value=${String(message.value)} source=${message.source || "unknown"} payload=${JSON.stringify(message.payload || {})}`);
420
+ console.log(`[Glomo-RN-SDK LRS] Education carousel signal received: value=${String(message.value)} source=${message.source || "unknown"} payload=${JSON.stringify(message.payload || {})}`);
445
421
  }
446
422
  (0, analytics_1.trackEducationStepsShown)(orderId, publicKey, devMode, mockMode, checkoutUrl, message.source);
447
423
  setEducationCarouselState(nextState);
@@ -450,37 +426,38 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
450
426
  }
451
427
  catch (error) {
452
428
  if (devMode) {
453
- console.error("[GlomoPay RN SDK] Error parsing EducationCarouselWebView message:", error);
429
+ console.error("[Glomo-RN-SDK LRS] Error parsing EducationCarouselWebView message:", error);
454
430
  }
455
431
  }
456
432
  }, [checkoutUrl, devMode, mockMode, orderId, publicKey]);
457
433
  // Handler for the navigation state changes
458
434
  const handleNavigationStateChange = (0, react_1.useCallback)((navState) => {
459
435
  if (devMode) {
460
- console.log("[GlomoPay RN SDK] Navigation state:", navState);
436
+ console.log("[Glomo-RN-SDK LRS] Navigation state:", navState);
461
437
  }
462
438
  }, [devMode]);
463
439
  // Handler for the modal back button press events
464
440
  const handleModalBackButton = (0, react_1.useCallback)(() => {
465
441
  try {
466
442
  if (devMode) {
467
- console.log("[GlomoPay RN SDK] Modal dismissed/back button pressed");
443
+ console.log("[Glomo-RN-SDK LRS] Modal dismissed/back button pressed");
468
444
  }
469
445
  if (showFlowWebView) {
470
446
  setShowFlowWebView(false);
471
447
  setFlowWebViewUrl("");
472
- setEducationCarouselState("pending");
473
448
  }
449
+ // Resetting carousel state and closing the checkout modal regardless of flow WebView state
450
+ setEducationCarouselState("pending");
474
451
  setShowCheckout(false);
475
452
  if (status === "payment_in_progress") {
476
453
  if (devMode) {
477
- console.log("[GlomoPay RN SDK] In progress payment cancelled");
454
+ console.log("[Glomo-RN-SDK LRS] In progress payment cancelled");
478
455
  }
479
456
  setStatus("payment_cancelled");
480
457
  }
481
458
  else {
482
459
  if (devMode) {
483
- console.log("[GlomoPay RN SDK] Ignoring checkout status update for: " + status);
460
+ console.log("[Glomo-RN-SDK LRS] Ignoring checkout status update for: " + status);
484
461
  }
485
462
  }
486
463
  (0, validation_1.safeCallback)(onPaymentTerminate, [], "onPaymentTerminate", devMode);
@@ -490,14 +467,14 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
490
467
  }
491
468
  catch (error) {
492
469
  if (devMode) {
493
- console.error("[GlomoPay RN SDK] Error in handleModalBackButton:", error);
470
+ console.error("[Glomo-RN-SDK LRS] Error in handleModalBackButton:", error);
494
471
  }
495
472
  }
496
473
  }, [showFlowWebView, devMode, onPaymentTerminate, status, orderId, publicKey, mockMode, checkoutUrl]);
497
474
  /** Closes the flow WebView and returns to the main checkout */
498
475
  const handleFlowBack = (0, react_1.useCallback)(() => {
499
476
  if (devMode) {
500
- console.log("[GlomoPay RN SDK] Flow WebView back button pressed");
477
+ console.log("[Glomo-RN-SDK LRS] Flow WebView back button pressed");
501
478
  }
502
479
  setShowFlowWebView(false);
503
480
  setFlowWebViewUrl("");
@@ -528,14 +505,14 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
528
505
  jailbreakDetected: deviceComplianceCheck,
529
506
  };
530
507
  if (devMode) {
531
- console.log(`[GlomoPay RN SDK] Attempting to start checkout of ${checkoutUrl} from status: ${status}`);
508
+ console.log(`[Glomo-RN-SDK LRS] Attempting to start checkout of ${checkoutUrl} from status: ${status}`);
532
509
  }
533
510
  // Tracking start attempt with current status
534
511
  (0, analytics_1.trackStartAttempt)(status, orderId, publicKey, devMode, mockMode, checkoutUrl, jailbreakDetectionInfo);
535
512
  if (deviceComplianceCheck === true) {
536
513
  // Device detected as compromised
537
514
  if (devMode) {
538
- console.error("[GlomoPay RN SDK] Cannot start checkout. Device is rooted or jailbroken.");
515
+ console.error("[Glomo-RN-SDK LRS] Cannot start checkout. Device is rooted or jailbroken.");
539
516
  }
540
517
  const errors = [
541
518
  {
@@ -551,7 +528,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
551
528
  }
552
529
  else if (deviceComplianceCheck === null) {
553
530
  // This warning was intentionally not gated behind a devMode check to ensure merchants are aware of the strong recommendation to install jail-monkey for enhanced security compliance.
554
- console.warn("[GlomoPay RN SDK] Device security library not installed - the SDK won't be able to automatically detect rooted/jailbroken devices. It is HIGHLY recommended to install jail-monkey as per the README, and prevent LRS checkouts from compromised devices.");
531
+ console.warn("[Glomo-RN-SDK LRS] Device security library not installed - the SDK won't be able to automatically detect rooted/jailbroken devices. It is HIGHLY recommended to install jail-monkey as per the README, and prevent LRS checkouts from compromised devices.");
555
532
  }
556
533
  // Enforcing devMode requirement for development servers
557
534
  const resolvedServer = server || "prod";
@@ -602,7 +579,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
602
579
  }
603
580
  if (errors.length > 0) {
604
581
  if (devMode) {
605
- console.error(`[GlomoPay RN SDK] Cannot start checkout. Validation failed.`);
582
+ console.error(`[Glomo-RN-SDK LRS] Cannot start checkout. Validation failed.`);
606
583
  }
607
584
  (0, validation_1.safeCallback)(onSdkError, [errors], "onSdkError", devMode);
608
585
  // Tracking start() failure
@@ -613,7 +590,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
613
590
  }
614
591
  if (status === "payment_successful") {
615
592
  if (devMode) {
616
- console.log(`[GlomoPay RN SDK] Cannot start checkout. Current status: ${status}. Payment already successful.`);
593
+ console.log(`[Glomo-RN-SDK LRS] Cannot start checkout. Current status: ${status}. Payment already successful.`);
617
594
  }
618
595
  // Tracking start() failure
619
596
  (0, analytics_1.trackStartFailure)("payment_successful", orderId, publicKey, devMode, mockMode, checkoutUrl, jailbreakDetectionInfo);
@@ -623,9 +600,11 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
623
600
  if (status !== "ready" &&
624
601
  status !== "payment_cancelled" &&
625
602
  status !== "payment_failed" &&
626
- status !== "payment_in_progress") {
603
+ status !== "payment_in_progress" &&
604
+ status !== "bank_transfer_submitted" &&
605
+ status !== "pay_via_bank_completed") {
627
606
  if (devMode) {
628
- console.log(`[GlomoPay RN SDK] Cannot start checkout. Unknown status: ${status}.`);
607
+ console.log(`[Glomo-RN-SDK LRS] Cannot start checkout. Unknown status: ${status}.`);
629
608
  }
630
609
  // Tracking start() failure
631
610
  (0, analytics_1.trackStartFailure)("invalid_status", orderId, publicKey, devMode, mockMode, checkoutUrl, jailbreakDetectionInfo);
@@ -634,7 +613,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
634
613
  }
635
614
  if (!checkoutUrl) {
636
615
  if (devMode) {
637
- console.error("[GlomoPay RN SDK] Cannot start checkout. Invalid checkout URL.");
616
+ console.error("[Glomo-RN-SDK LRS] Cannot start checkout. Invalid checkout URL.");
638
617
  }
639
618
  // Tracking start() failure
640
619
  (0, analytics_1.trackStartFailure)("invalid_url", orderId, publicKey, devMode, mockMode, checkoutUrl, jailbreakDetectionInfo);
@@ -642,7 +621,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
642
621
  return false;
643
622
  }
644
623
  if (devMode) {
645
- console.log("[GlomoPay RN SDK] Starting checkout from previous state: " + status);
624
+ console.log("[Glomo-RN-SDK LRS] Starting checkout from previous state: " + status);
646
625
  }
647
626
  setShowFlowWebView(false);
648
627
  setFlowWebViewUrl("");
@@ -652,7 +631,7 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
652
631
  (0, analytics_1.trackStartSuccess)(orderId, publicKey, devMode, mockMode, checkoutUrl, jailbreakDetectionInfo);
653
632
  setShowCheckout(true);
654
633
  return true;
655
- }, [devMode, status, publicKey, orderId, baseCheckoutUrl, checkoutUrl, mockMode, onSdkError]);
634
+ }, [devMode, status, publicKey, orderId, baseCheckoutUrl, checkoutUrl, mockMode, onSdkError, server]);
656
635
  // Initializing Segment analytics
657
636
  (0, react_1.useEffect)(() => {
658
637
  (0, segment_1.initializeSegment)(devMode);
@@ -661,9 +640,13 @@ function useLrsCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymen
661
640
  (0, react_1.useEffect)(() => {
662
641
  if (orderId && publicKey) {
663
642
  // Only resetting the checkout flow if the current status is that of a terminal state
664
- if (status === "payment_successful" || status === "payment_failed" || status === "payment_cancelled") {
643
+ if (status === "payment_successful" ||
644
+ status === "payment_failed" ||
645
+ status === "payment_cancelled" ||
646
+ status === "bank_transfer_submitted" ||
647
+ status === "pay_via_bank_completed") {
665
648
  if (devMode) {
666
- console.log(`[GlomoPay RN SDK] Resetting checkout status ${status} for new orderId ${orderId} and publicKey ${publicKey}`);
649
+ console.log(`[Glomo-RN-SDK LRS] Resetting checkout status ${status} for new orderId ${orderId} and publicKey ${publicKey}`);
667
650
  }
668
651
  setStatus("ready");
669
652
  }
@@ -0,0 +1,74 @@
1
+ /** Main SDK hook for the GlomoPay Standard Checkout flow */
2
+ import React from "react";
3
+ import { type NativeSyntheticEvent } from "react-native";
4
+ import { type WebViewNavigation, type WebViewMessageEvent, type WebView } from "react-native-webview";
5
+ import { type GlomoServer } from "./config/base";
6
+ import { type SdkError, type CheckoutAnalyticsTrackers } from "./utils/analytics";
7
+ import { type GlomoBankTransferPayload, type GlomoPayViaBankConnectionPayload } from "./types/checkout";
8
+ import { type StandardCheckoutStatus, type GlomoStandardCheckoutPayload } from "./types/standard-checkout";
9
+ /** Android-only WebView permission request, not yet in react-native-webview type definitions */
10
+ export interface WebViewPermissionRequest {
11
+ nativeEvent: {
12
+ resources: string[];
13
+ };
14
+ grant: (resources: string[]) => void;
15
+ deny: () => void;
16
+ }
17
+ /** The options for the useStandardCheckout hook */
18
+ export interface UseStandardCheckoutOptions {
19
+ server?: GlomoServer;
20
+ publicKey: string;
21
+ orderId: string;
22
+ onPaymentSuccess: (payload: GlomoStandardCheckoutPayload) => void;
23
+ onPaymentFailure: (payload: GlomoStandardCheckoutPayload) => void;
24
+ onConnectionError?: (error: unknown) => void;
25
+ onPaymentTerminate?: () => void;
26
+ onSdkError?: (error: Array<SdkError>) => void;
27
+ onBankTransferSubmitted?: (payload: GlomoBankTransferPayload | null | undefined) => void;
28
+ onPayViaBankCompleted?: (payload: {
29
+ status: string;
30
+ }) => void;
31
+ onPayViaBankBankConnectionSuccessful?: (payload: GlomoPayViaBankConnectionPayload | null | undefined) => void;
32
+ onUserRefusedCameraPermissions?: () => void;
33
+ devMode?: boolean;
34
+ }
35
+ /** The return values for the useStandardCheckout hook */
36
+ export interface UseStandardCheckoutReturn {
37
+ start: () => boolean;
38
+ status: StandardCheckoutStatus;
39
+ showCheckout: boolean;
40
+ flowWebViewUrl: string;
41
+ showFlowWebView: boolean;
42
+ checkoutUrl: string;
43
+ mainWebViewRef: React.RefObject<WebView>;
44
+ flowWebViewRef: React.RefObject<WebView>;
45
+ handleMainWebViewMessage: (event: WebViewMessageEvent) => void;
46
+ handleFlowWebViewMessage: (event: WebViewMessageEvent) => void;
47
+ handleError: (syntheticEvent: NativeSyntheticEvent<{
48
+ code?: number;
49
+ domain?: string;
50
+ description?: string;
51
+ }>) => void;
52
+ handleHttpError: (syntheticEvent: NativeSyntheticEvent<{
53
+ statusCode: number;
54
+ description?: string;
55
+ }>) => void;
56
+ handleNavigationStateChange: (navState: WebViewNavigation) => void;
57
+ handlePermissionRequest: (request: WebViewPermissionRequest) => void;
58
+ handleModalBackButton: () => void;
59
+ handleFlowBack: () => void;
60
+ injectedMain?: string;
61
+ injectedFlow?: string;
62
+ }
63
+ /**
64
+ * Internal options for useStandardCheckout.
65
+ * Used by subscription checkout to inject subscription-specific analytics trackers.
66
+ * Not exported to merchants.
67
+ */
68
+ export interface UseStandardCheckoutInternalOptions {
69
+ analyticsTrackers?: CheckoutAnalyticsTrackers;
70
+ _skipOrderIdValidation?: boolean;
71
+ }
72
+ /** The main SDK hook for the GlomoPay Standard Checkout flow */
73
+ export declare function useStandardCheckout({ server, publicKey, orderId, onPaymentSuccess, onPaymentFailure, onConnectionError, onPaymentTerminate, onSdkError, onBankTransferSubmitted, onPayViaBankCompleted, onPayViaBankBankConnectionSuccessful, onUserRefusedCameraPermissions, devMode, }: UseStandardCheckoutOptions, mockMode: boolean, internalOptions?: UseStandardCheckoutInternalOptions): UseStandardCheckoutReturn;
74
+ //# sourceMappingURL=use-standard-checkout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-standard-checkout.d.ts","sourceRoot":"","sources":["../src/use-standard-checkout.tsx"],"names":[],"mappings":"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"}