@glomopay/react-native-sdk 3.0.1 → 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 (40) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/MIGRATION.md +50 -0
  3. package/README.md +131 -50
  4. package/lib/glomo-checkout.d.ts.map +1 -1
  5. package/lib/glomo-checkout.js +38 -1
  6. package/lib/glomo-standard-checkout.d.ts +20 -0
  7. package/lib/glomo-standard-checkout.d.ts.map +1 -1
  8. package/lib/glomo-standard-checkout.js +14 -3
  9. package/lib/glomo-subscriptions-checkout.d.ts +8 -0
  10. package/lib/glomo-subscriptions-checkout.d.ts.map +1 -0
  11. package/lib/glomo-subscriptions-checkout.js +85 -0
  12. package/lib/index.d.ts +1 -1
  13. package/lib/index.d.ts.map +1 -1
  14. package/lib/types/checkout.d.ts +15 -3
  15. package/lib/types/checkout.d.ts.map +1 -1
  16. package/lib/types/subscriptions-checkout.d.ts +29 -0
  17. package/lib/types/subscriptions-checkout.d.ts.map +1 -0
  18. package/lib/types/subscriptions-checkout.js +3 -0
  19. package/lib/use-glomo-checkout.d.ts +34 -4
  20. package/lib/use-glomo-checkout.d.ts.map +1 -1
  21. package/lib/use-glomo-checkout.js +92 -13
  22. package/lib/use-standard-checkout.d.ts +11 -2
  23. package/lib/use-standard-checkout.d.ts.map +1 -1
  24. package/lib/use-standard-checkout.js +52 -35
  25. package/lib/utils/analytics.d.ts +87 -2
  26. package/lib/utils/analytics.d.ts.map +1 -1
  27. package/lib/utils/analytics.js +356 -15
  28. package/lib/utils/device-compliance.d.ts.map +1 -1
  29. package/lib/utils/device-compliance.js +0 -1
  30. package/package.json +15 -4
  31. package/src/glomo-checkout.tsx +79 -5
  32. package/src/glomo-standard-checkout.tsx +33 -4
  33. package/src/glomo-subscriptions-checkout.tsx +83 -0
  34. package/src/index.ts +1 -1
  35. package/src/types/checkout.ts +10 -3
  36. package/src/types/subscriptions-checkout.ts +31 -0
  37. package/src/use-glomo-checkout.tsx +158 -17
  38. package/src/use-standard-checkout.tsx +70 -52
  39. package/src/utils/analytics.ts +482 -17
  40. package/src/utils/device-compliance.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.1.0] - 2026-06-08
9
+
10
+ ### Added
11
+
12
+ - **Subscriptions checkout support** - new `subscriptionId` prop on `GlomoCheckout`. When provided, the SDK bypasses order type detection and renders the subscriptions checkout flow directly. No API call is made - the inner checkout component mounts immediately. The `detecting_order_type` status is not emitted for subscription flows.
13
+ - **Mutual exclusion validation** - `GlomoCheckout` validates that exactly one of `orderId` or `subscriptionId` is provided. If both or neither are set, `onSdkError` fires with a clear message and `start()` returns `false`.
14
+
15
+ ### Changed
16
+
17
+ - **`orderId` is now optional** on `GlomoCheckoutProps` - required only when `subscriptionId` is absent.
18
+
19
+ ### Deprecated
20
+
21
+ - **`useGlomoCheckout` hook** - use the `GlomoCheckout` component with a ref instead. The hook does not provide reactive state - `getStatus()` returns a point-in-time snapshot. Will be removed in a future major version.
22
+
8
23
  ## [3.0.1] - 2026-06-02
9
24
 
10
25
  ### Added
package/MIGRATION.md ADDED
@@ -0,0 +1,50 @@
1
+ # Migration Guide
2
+
3
+ ## v2 to v3
4
+
5
+ v3 replaces the LRS-only `GlomoLrsCheckout` with a unified `GlomoCheckout` that auto-detects order type.
6
+
7
+ ### Renamed Exports
8
+
9
+ | v2 | v3 |
10
+ | -------------------------- | ------------------------- |
11
+ | `GlomoLrsCheckout` | `GlomoCheckout` |
12
+ | `GlomoLrsCheckoutRef` | `GlomoCheckoutRef` |
13
+ | `GlomoLrsCheckoutProps` | `GlomoCheckoutProps` |
14
+ | `GlomoLrsCheckoutPayload` | `GlomoCheckoutPayload` |
15
+ | `GlomoLrsServer` | `GlomoServer` |
16
+
17
+ ### Breaking Changes
18
+
19
+ - **`start()` is now async**: Returns `Promise<boolean>` instead of `boolean`. Update call sites to `await ref.current?.start()`.
20
+ - **New statuses**: `bank_transfer_submitted` and `pay_via_bank_completed` are new additions to `CheckoutStatus`.
21
+ - **New callbacks**: `onBankTransferSubmitted`, `onPayViaBankCompleted`, and `onUserRefusedCameraPermissions` are available.
22
+
23
+ ### Before / After
24
+
25
+ **v2:**
26
+ ```tsx
27
+ import { GlomoLrsCheckout, type GlomoLrsCheckoutRef } from "@glomopay/react-native-sdk";
28
+
29
+ const ref = useRef<GlomoLrsCheckoutRef>(null);
30
+ const started = ref.current?.start(); // boolean
31
+ ```
32
+
33
+ **v3:**
34
+ ```tsx
35
+ import { GlomoCheckout, type GlomoCheckoutRef } from "@glomopay/react-native-sdk";
36
+
37
+ const ref = useRef<GlomoCheckoutRef>(null);
38
+ const started = await ref.current?.start(); // Promise<boolean>
39
+ ```
40
+
41
+ ### Platform Configuration (New in v3)
42
+
43
+ Checkout flows with camera-based bank authentication require native permissions:
44
+
45
+ - **Android** (`AndroidManifest.xml`): `<uses-permission android:name="android.permission.CAMERA" />`
46
+ - **iOS** (`Info.plist`): `NSCameraUsageDescription` key
47
+
48
+ These are only required for flows that use camera-based bank authentication.
49
+
50
+ For the full changelog, see CHANGELOG.md included in this package.
package/README.md CHANGED
@@ -1,28 +1,16 @@
1
- # GlomoPay React Native SDK 💳
1
+ # GlomoPay React Native SDK
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@glomopay/react-native-sdk.svg)](https://www.npmjs.com/package/@glomopay/react-native-sdk)
4
4
  [![License](https://img.shields.io/npm/l/@glomopay/react-native-sdk.svg)](LICENSE)
5
5
 
6
6
  Official React Native SDK for integrating GlomoPay payment checkout flows into your mobile applications.
7
7
 
8
- ## ✨ Features
9
-
10
- - 📱 **Cross-platform** - works on both iOS and Android
11
- - 🔷 **TypeScript** - full type definitions for all exports
12
- - ⚡ **Unified checkout** - renders the correct checkout flow automatically based on your order
13
- - 💰 **Bank transfer support** - callback for bank transfer submission events
14
- - 🏦 **Pay via bank** - bank payment flow completion and connection callbacks
15
- - 📷 **Camera permissions** - built-in handling for bank authentication
16
- - 🔒 **Device security** - optional **(but strongly recommended)** `jail-monkey` integration for rooted/jailbroken device detection
17
- - 🛡️ **Input validation** - publicKey and orderId format enforcement before checkout starts
18
- - 🧪 **Mock mode** - test with `test_` / `mock_` prefixed keys without hitting production
19
-
20
- ## 📋 Prerequisites
8
+ ## Prerequisites
21
9
 
22
10
  - API credentials (Public Key) from your GlomoPay dashboard
23
11
  - An order ID created via the GlomoPay API
24
12
 
25
- ## 🛠️ System Requirements
13
+ ## System Requirements
26
14
 
27
15
  | Requirement | Version |
28
16
  | ---------------------- | ------------ |
@@ -33,15 +21,7 @@ Official React Native SDK for integrating GlomoPay payment checkout flows into y
33
21
  | react-native-webview | ^13.0.0 |
34
22
  | jail-monkey (optional) | ^2.6.0 |
35
23
 
36
- ## ⚠️ Breaking Changes (v3)
37
-
38
- - `GlomoLrsCheckout` has been replaced by `GlomoCheckout` - the new component now works for all checkout orders (including LRS)
39
- - `start()` is now async - returns `Promise<boolean>` instead of `boolean`
40
- - All LRS-specific exports have been renamed (e.g. `GlomoLrsCheckoutRef` -> `GlomoCheckoutRef`)
41
-
42
- For the full list of changes and migration details, see [CHANGELOG.md](./CHANGELOG.md) and [Migration from v2](#-migration-from-v2).
43
-
44
- ## 📦 Installation
24
+ ## Installation
45
25
 
46
26
  ### React Native CLI
47
27
 
@@ -66,7 +46,7 @@ npm install jail-monkey
66
46
 
67
47
  The SDK works without `jail-monkey`, but installing it enables automatic device security checks. Without it, the SDK logs a warning on every `start()` call.
68
48
 
69
- ## 🚀 Quick Start
49
+ ## Quick Start
70
50
 
71
51
  ```tsx
72
52
  import React, { useRef } from "react";
@@ -129,7 +109,86 @@ export default function PaymentScreen() {
129
109
  }
130
110
  ```
131
111
 
132
- ## 📚 API Reference
112
+ ## Breaking Changes (v3)
113
+
114
+ - `GlomoLrsCheckout` has been replaced by `GlomoCheckout` - the new component now works for all checkout orders (including LRS)
115
+ - `start()` is now async - returns `Promise<boolean>` instead of `boolean`
116
+ - All LRS-specific exports have been renamed (e.g. `GlomoLrsCheckoutRef` -> `GlomoCheckoutRef`)
117
+
118
+ For migration details, see the [Migration from v2](#migration-from-v2) section below or MIGRATION.md included in this package.
119
+
120
+ ## Subscriptions Checkout
121
+
122
+ To process subscription payments, pass a `subscriptionId` instead of an `orderId`:
123
+
124
+ ```tsx
125
+ <GlomoCheckout
126
+ ref={checkoutRef}
127
+ publicKey="live_pk_abc123"
128
+ subscriptionId="sub_xyz789"
129
+ onPaymentSuccess={(payload) => {
130
+ console.log("Subscription payment success:", payload.paymentId);
131
+ }}
132
+ onPaymentFailure={(payload) => {
133
+ console.log("Subscription payment failed:", payload.paymentId);
134
+ }}
135
+ onSdkError={(errors) => {
136
+ errors.forEach((e) => console.error(e.type, e.message));
137
+ }}
138
+ />
139
+ ```
140
+
141
+ When `subscriptionId` is provided:
142
+ - The SDK skips order type detection (no API call)
143
+ - The `subscriptionId` must start with `sub_`
144
+ - Bank transfer callbacks (`onBankTransferSubmitted`, `onPayViaBankCompleted`) are not applicable - subscriptions are card-only
145
+ - Do not pass both `orderId` and `subscriptionId` - the SDK will fire `onSdkError`
146
+ - The `detecting_order_type` status is not emitted for subscription flows
147
+
148
+ ## Features
149
+
150
+ - **Cross-platform** - works on both iOS and Android
151
+ - **TypeScript** - full type definitions for all exports
152
+ - **Unified checkout** - renders the correct checkout flow automatically based on your order
153
+ - **Bank transfer support** - callback for bank transfer submission events
154
+ - **Pay via bank** - bank payment flow completion and connection callbacks
155
+ - **Camera permissions** - built-in handling for bank authentication
156
+ - **Device security** - optional **(but strongly recommended)** `jail-monkey` integration for rooted/jailbroken device detection
157
+ - **Input validation** - publicKey and orderId format enforcement before checkout starts
158
+ - **Mock mode** - test with `test_` / `mock_` prefixed keys without hitting production
159
+
160
+ ## useGlomoCheckout Hook (Deprecated)
161
+
162
+ > **Deprecated** - Legacy hook, will be removed in a future major version.
163
+
164
+ `useGlomoCheckout` is a legacy placeholder from the v1.x hook-based API. In v1.x, the equivalent
165
+ hook (`useLrsCheckout`) provided reactive WebView state and rendering primitives that merchants used
166
+ to build custom checkout UIs. In v3, the inner checkout components are no longer exported, making
167
+ this hook ineffective for custom rendering.
168
+
169
+ The hook's public return type (`UseGlomoCheckoutReturn`) exposes:
170
+ - `start()` - identical to `GlomoCheckoutRef.start()`. Returns `Promise<boolean>`.
171
+ - `getStatus()` - returns a point-in-time `CheckoutStatus` snapshot. **Not reactive** - does not
172
+ trigger re-renders when status changes.
173
+
174
+ **Use the `GlomoCheckout` component with a ref instead:**
175
+
176
+ ```tsx
177
+ import React, { useRef } from "react";
178
+ import { GlomoCheckout, type GlomoCheckoutRef } from "@glomopay/react-native-sdk";
179
+
180
+ const checkoutRef = useRef<GlomoCheckoutRef>(null);
181
+
182
+ // Start checkout
183
+ const started = await checkoutRef.current?.start();
184
+
185
+ // Check status (point-in-time, same as hook)
186
+ const status = checkoutRef.current?.getStatus();
187
+ ```
188
+
189
+ The component-based API provides the same functionality with proper lifecycle management.
190
+
191
+ ## API Reference
133
192
 
134
193
  ### GlomoCheckout Component
135
194
 
@@ -144,7 +203,8 @@ The unified checkout component. Place it in your render tree and control it via
144
203
  | Prop | Type | Required | Description |
145
204
  | -------------------------------- | ----------------------------------------------- | -------- | ------------------------------------------------------------------- |
146
205
  | `publicKey` | `string` | Yes | Your GlomoPay public key (must start with `live_`, `mock_`, or `test_`) |
147
- | `orderId` | `string` | Yes | Order ID from the GlomoPay API (must start with `order_`) |
206
+ | `orderId` | `string` | No* | Order ID from the GlomoPay API (must start with `order_`) |
207
+ | `subscriptionId` | `string` | No* | Subscription ID (must start with `sub_`). Bypasses order type detection. |
148
208
  | `onPaymentSuccess` | `(payload: GlomoCheckoutPayload) => void` | Yes | Called when payment succeeds |
149
209
  | `onPaymentFailure` | `(payload: GlomoCheckoutPayload) => void` | Yes | Called when payment fails |
150
210
  | `onConnectionError` | `(error: unknown) => void` | No | Called on network/connection errors |
@@ -155,6 +215,8 @@ The unified checkout component. Place it in your render tree and control it via
155
215
  | `onPayViaBankBankConnectionSuccessful` | `(payload: GlomoPayViaBankConnectionPayload \| null \| undefined) => void` | No | Called when bank connection is established during pay via bank flow |
156
216
  | `onUserRefusedCameraPermissions` | `() => void` | No | Called when user denies camera access needed for bank authentication |
157
217
 
218
+ *Exactly one of `orderId` or `subscriptionId` must be provided. If both or neither are set, `onSdkError` fires and `start()` returns `false`.
219
+
158
220
  #### Ref Methods (`GlomoCheckoutRef`)
159
221
 
160
222
  | Method | Signature | Description |
@@ -167,6 +229,7 @@ The unified checkout component. Place it in your render tree and control it via
167
229
  | Status | Description |
168
230
  | -------------------------- | -------------------------------------------------------------- |
169
231
  | `ready` | Initial state - checkout can be started |
232
+ | `detecting_order_type` | Order type detection in progress (after `start()`, before checkout opens) |
170
233
  | `payment_in_progress` | Checkout modal is open, user is interacting |
171
234
  | `payment_successful` | Payment completed successfully. Cannot restart with same order |
172
235
  | `payment_failed` | Payment failed. Can retry with same order |
@@ -214,11 +277,11 @@ interface GlomoPayViaBankConnectionPayload {
214
277
  interface SdkError {
215
278
  type: "validation_error" | "device_forbidden";
216
279
  message: string;
217
- field?: string;
280
+ field?: "publicKey" | "orderId" | "subscriptionId" | "baseCheckoutUrl" | "generatedCheckoutUrl";
218
281
  }
219
282
  ```
220
283
 
221
- ## 💰 Bank Transfer Support
284
+ ## Bank Transfer Support
222
285
 
223
286
  When the checkout flow includes a bank transfer option, the user submits transfer details (account number, reference) through the checkout UI. The SDK fires `onBankTransferSubmitted` with a `GlomoBankTransferPayload`:
224
287
 
@@ -231,7 +294,7 @@ onBankTransferSubmitted={(payload) => {
231
294
 
232
295
  The checkout status transitions to `bank_transfer_submitted`.
233
296
 
234
- ## 🏦 Pay via Bank Support
297
+ ## Pay via Bank Support
235
298
 
236
299
  The SDK fires `onPayViaBankCompleted` when the pay-via-bank journey completes:
237
300
 
@@ -254,7 +317,7 @@ onPayViaBankBankConnectionSuccessful={(payload) => {
254
317
  }}
255
318
  ```
256
319
 
257
- ## 📷 Camera Permissions for bank authentication
320
+ ## Camera Permissions
258
321
 
259
322
  Some checkout flows may require camera access for bank authentication. The SDK handles permission prompts automatically, but you must declare the permissions in your native project config.
260
323
 
@@ -280,12 +343,12 @@ Add to `ios/<YourApp>/Info.plist`:
280
343
  - **Android**: SDK prompts the user via a native permission dialog. If denied, checkout closes and `onUserRefusedCameraPermissions` fires.
281
344
  - **iOS**: SDK grants the WebView permission request; iOS shows its own system prompt. If the user denies at the system level, the WebView handles the denial.
282
345
 
283
- ## 📱 Platform Behavior
346
+ ## Platform Behavior
284
347
 
285
348
  - **iOS**: Checkout opens as a `pageSheet` modal (swipe-down to dismiss). Dismissing fires `onPaymentTerminate`.
286
349
  - **Android**: Checkout opens fullscreen. The hardware back button dismisses it and fires `onPaymentTerminate`.
287
350
 
288
- ## 🔒 Device Security Compliance
351
+ ## Device Security Compliance
289
352
 
290
353
  The SDK optionally integrates with `jail-monkey` to detect rooted (Android) or jailbroken (iOS) devices.
291
354
 
@@ -293,7 +356,7 @@ The SDK optionally integrates with `jail-monkey` to detect rooted (Android) or j
293
356
  - If `jail-monkey` is installed and the device is clean: checkout proceeds normally.
294
357
  - If `jail-monkey` is not installed: SDK logs a warning and proceeds without checking. This is not recommended for production deployments handling regulated transactions.
295
358
 
296
- ## 🧪 Mock Mode
359
+ ## Mock Mode
297
360
 
298
361
  The SDK infers mock mode from the `publicKey` prefix:
299
362
 
@@ -305,7 +368,7 @@ The SDK infers mock mode from the `publicKey` prefix:
305
368
 
306
369
  Mock mode keys route to the sandbox backend. No real transactions are created.
307
370
 
308
- ## 🌐 Connection Handling
371
+ ## Connection Handling
309
372
 
310
373
  The SDK detects connection errors from the WebView and fires `onConnectionError`:
311
374
 
@@ -314,18 +377,21 @@ The SDK detects connection errors from the WebView and fires `onConnectionError`
314
377
 
315
378
  The checkout modal is automatically dismissed on connection errors.
316
379
 
317
- ## 🛡️ Input Validation
380
+ ## Input Validation
318
381
 
319
382
  The SDK validates inputs before starting the checkout:
320
383
 
321
- | Field | Rule |
322
- | ----------- | ----------------------------------------------- |
323
- | `publicKey` | Must start with `live_`, `mock_`, or `test_`. Min 6 characters. |
324
- | `orderId` | Must start with `order_`. Min 7 characters. |
384
+ | Field | Rule |
385
+ | ---------------- | ----------------------------------------------- |
386
+ | `publicKey` | Must start with `live_`, `mock_`, or `test_`. Min 6 characters. |
387
+ | `orderId` | Must start with `order_`. Min 7 characters. Required when `subscriptionId` is absent. |
388
+ | `subscriptionId` | Must start with `sub_`. Trimmed and checked for emptiness. Required when `orderId` is absent. |
325
389
 
326
390
  Validation failures fire `onSdkError` with `type: "validation_error"` and the relevant `field` name. `start()` returns `false`.
327
391
 
328
- ## 🔄 Migration from v2
392
+ Providing both `orderId` and `subscriptionId` (or neither) also fires `onSdkError`.
393
+
394
+ ## Migration from v2
329
395
 
330
396
  v3 replaces the LRS-only `GlomoLrsCheckout` with a unified `GlomoCheckout`.
331
397
 
@@ -345,15 +411,17 @@ v3 replaces the LRS-only `GlomoLrsCheckout` with a unified `GlomoCheckout`.
345
411
  - **New statuses**: `bank_transfer_submitted` and `pay_via_bank_completed` are new additions to `CheckoutStatus`.
346
412
  - **New callbacks**: `onBankTransferSubmitted`, `onPayViaBankCompleted`, and `onUserRefusedCameraPermissions` are available.
347
413
 
348
- For the full list of changes, see [CHANGELOG.md](./CHANGELOG.md).
414
+ See MIGRATION.md included in this package for a standalone migration guide with before/after code examples.
349
415
 
350
- ## 🚨 Troubleshooting
416
+ ## Troubleshooting
351
417
 
352
418
  ### `start()` returns `false`
353
419
 
354
420
  Check `onSdkError` for details. Common causes:
355
421
  - Invalid `publicKey` format (must start with `live_`, `mock_`, or `test_`)
356
422
  - Invalid `orderId` format (must start with `order_`)
423
+ - Invalid `subscriptionId` format (must start with `sub_`, non-empty after trimming)
424
+ - Both `orderId` and `subscriptionId` provided (or neither)
357
425
  - Device is rooted/jailbroken (when `jail-monkey` is installed)
358
426
 
359
427
  ### Checkout opens but shows a blank screen
@@ -370,12 +438,15 @@ Check `onSdkError` for details. Common causes:
370
438
 
371
439
  - Ensure you are passing `onPayViaBankCompleted` as a prop to `GlomoCheckout`
372
440
 
373
- ## 🔍 Exports
441
+ ## Exports
374
442
 
375
443
  ```ts
376
- // Component
444
+ // Components
377
445
  export { GlomoCheckout } from "@glomopay/react-native-sdk";
378
446
 
447
+ // Hooks (deprecated - use GlomoCheckout component with ref instead)
448
+ export { useGlomoCheckout } from "@glomopay/react-native-sdk";
449
+
379
450
  // Types
380
451
  export type {
381
452
  GlomoCheckoutRef,
@@ -384,18 +455,28 @@ export type {
384
455
  CheckoutStatus,
385
456
  GlomoBankTransferPayload,
386
457
  GlomoPayViaBankConnectionPayload,
458
+ UseGlomoCheckoutReturn, // deprecated
387
459
  SdkError,
388
460
  } from "@glomopay/react-native-sdk";
389
-
390
- // Hook (advanced usage)
391
- export { useGlomoCheckout } from "@glomopay/react-native-sdk";
392
461
  ```
393
462
 
394
- ## 💬 Support
463
+ ## Security
464
+
465
+ The SDK loads checkout pages in an isolated WebView. No PAN, CVV, or sensitive payment data passes through the React Native bridge - all sensitive input is handled within the WebView's sandboxed context.
466
+
467
+ Device integrity checking is available via optional `jail-monkey` integration (see [Device Security Compliance](#device-security-compliance)).
468
+
469
+ To report a security vulnerability, email security@glomopay.com. Do not open a public GitHub issue for security reports.
470
+
471
+ ## Contributing
472
+
473
+ This SDK is maintained by GlomoPay. We do not accept external contributions at this time.
474
+
475
+ ## Support
395
476
 
396
477
  - GitHub Issues: https://github.com/glomopay/glomopay-rn-sdk/issues
397
478
  - Email: developer@glomopay.com
398
479
 
399
- ## 📄 License
480
+ ## License
400
481
 
401
482
  Apache-2.0. See [LICENSE](LICENSE) for details.
@@ -1 +1 @@
1
- {"version":3,"file":"glomo-checkout.d.ts","sourceRoot":"","sources":["../src/glomo-checkout.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA0C,MAAM,OAAO,CAAC;AAG/D,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AA8DlF,eAAO,MAAM,aAAa,6FAA2E,CAAC"}
1
+ {"version":3,"file":"glomo-checkout.d.ts","sourceRoot":"","sources":["../src/glomo-checkout.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsE,MAAM,OAAO,CAAC;AAG3F,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAwIlF,eAAO,MAAM,aAAa,6FAA2E,CAAC"}
@@ -40,16 +40,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
40
40
  exports.GlomoCheckout = void 0;
41
41
  const react_1 = __importStar(require("react"));
42
42
  const use_glomo_checkout_1 = require("./use-glomo-checkout");
43
+ const analytics_1 = require("./utils/analytics");
43
44
  const glomo_lrs_checkout_1 = require("./glomo-lrs-checkout");
44
45
  const glomo_standard_checkout_1 = require("./glomo-standard-checkout");
46
+ const glomo_subscriptions_checkout_1 = require("./glomo-subscriptions-checkout");
45
47
  function GlomoCheckoutComponent(props, ref) {
48
+ var _a;
46
49
  // useGlomoCheckout handles order type detection and exposes start/getStatus for the ref
47
- const { orderType, start, getStatus, innerLrsRef, innerStandardRef, props: passedProps } = (0, use_glomo_checkout_1.useGlomoCheckout)(props);
50
+ const { orderType, start, getStatus, innerLrsRef, innerStandardRef, innerSubscriptionsRef, props: passedProps, } = (0, use_glomo_checkout_1.useGlomoCheckout)(props, { _suppressDeprecationWarning: true });
48
51
  // Exposing start() and getStatus() via the forwarded ref for the merchant to call
49
52
  (0, react_1.useImperativeHandle)(ref, () => ({
50
53
  start,
51
54
  getStatus,
52
55
  }));
56
+ // Tracking unsupported callback props on subscription flows (fires once per mount)
57
+ const hasTrackedUnsupportedRef = (0, react_1.useRef)(false);
58
+ const devMode = (_a = passedProps.devMode) !== null && _a !== void 0 ? _a : false;
59
+ const mockMode = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = passedProps.publicKey) === null || _a === void 0 ? void 0 : _a.toLowerCase().startsWith("test_")) !== null && _b !== void 0 ? _b : false; }, [passedProps.publicKey]);
60
+ // Extracting stable booleans for the tracking effect to avoid depending on passedProps object
61
+ const hasBankTransferCallback = !!passedProps.onBankTransferSubmitted;
62
+ const hasPayViaBankCallback = !!passedProps.onPayViaBankCompleted;
63
+ const hasBankConnectionCallback = !!passedProps.onPayViaBankBankConnectionSuccessful;
64
+ (0, react_1.useEffect)(() => {
65
+ if (orderType !== "subscriptions" || hasTrackedUnsupportedRef.current)
66
+ return;
67
+ hasTrackedUnsupportedRef.current = true;
68
+ const unsupported = [
69
+ hasBankTransferCallback && "onBankTransferSubmitted",
70
+ hasPayViaBankCallback && "onPayViaBankCompleted",
71
+ hasBankConnectionCallback && "onPayViaBankBankConnectionSuccessful",
72
+ ].filter(Boolean);
73
+ for (const name of unsupported) {
74
+ (0, analytics_1.trackUseOfUnsupportedFunctionality)(name, passedProps.subscriptionId, passedProps.publicKey, devMode, mockMode, "");
75
+ }
76
+ }, [
77
+ orderType,
78
+ hasBankTransferCallback,
79
+ hasPayViaBankCallback,
80
+ hasBankConnectionCallback,
81
+ passedProps.subscriptionId,
82
+ passedProps.publicKey,
83
+ devMode,
84
+ mockMode,
85
+ ]);
53
86
  // Delegating to the LRS checkout component once order type is resolved as LRS
54
87
  if (orderType === "lrs") {
55
88
  return (<glomo_lrs_checkout_1.GlomoLrsCheckout ref={innerLrsRef} server={passedProps.server} publicKey={passedProps.publicKey} orderId={passedProps.orderId} onPaymentSuccess={passedProps.onPaymentSuccess} onPaymentFailure={passedProps.onPaymentFailure} onConnectionError={passedProps.onConnectionError} onPaymentTerminate={passedProps.onPaymentTerminate} onSdkError={passedProps.onSdkError} devMode={passedProps.devMode}/>);
@@ -58,6 +91,10 @@ function GlomoCheckoutComponent(props, ref) {
58
91
  if (orderType === "standard") {
59
92
  return (<glomo_standard_checkout_1.GlomoStandardCheckout ref={innerStandardRef} server={passedProps.server} publicKey={passedProps.publicKey} orderId={passedProps.orderId} onPaymentSuccess={passedProps.onPaymentSuccess} onPaymentFailure={passedProps.onPaymentFailure} onConnectionError={passedProps.onConnectionError} onPaymentTerminate={passedProps.onPaymentTerminate} onSdkError={passedProps.onSdkError} onBankTransferSubmitted={passedProps.onBankTransferSubmitted} onPayViaBankCompleted={passedProps.onPayViaBankCompleted} onPayViaBankBankConnectionSuccessful={passedProps.onPayViaBankBankConnectionSuccessful} onUserRefusedCameraPermissions={passedProps.onUserRefusedCameraPermissions} devMode={passedProps.devMode}/>);
60
93
  }
94
+ // Delegating to the Subscriptions checkout component when subscriptionId is provided (no API call)
95
+ if (orderType === "subscriptions") {
96
+ return (<glomo_subscriptions_checkout_1.GlomoSubscriptionsCheckout ref={innerSubscriptionsRef} server={passedProps.server} publicKey={passedProps.publicKey} subscriptionId={passedProps.subscriptionId} onPaymentSuccess={passedProps.onPaymentSuccess} onPaymentFailure={passedProps.onPaymentFailure} onConnectionError={passedProps.onConnectionError} onPaymentTerminate={passedProps.onPaymentTerminate} onSdkError={passedProps.onSdkError} onPayViaBankBankConnectionSuccessful={passedProps.onPayViaBankBankConnectionSuccessful} onUserRefusedCameraPermissions={passedProps.onUserRefusedCameraPermissions} devMode={passedProps.devMode}/>);
97
+ }
61
98
  /**
62
99
  * No modal for detecting state - avoids iOS pageSheet conflict where
63
100
  * dismissing the detecting modal interferes with the checkout modal presentation.
@@ -1,5 +1,25 @@
1
1
  /** The GlomoPay Standard Checkout Component */
2
2
  import React from "react";
3
3
  import { type GlomoStandardCheckoutRef, type GlomoStandardCheckoutProps } from "./types/standard-checkout";
4
+ import { type CheckoutAnalyticsTrackers } from "./utils/analytics";
5
+ /**
6
+ * Internal-only props for GlomoStandardCheckout.
7
+ * Used by GlomoSubscriptionsCheckout to inject subscription analytics trackers.
8
+ * Not exported to merchants via index.ts.
9
+ */
10
+ export interface GlomoStandardCheckoutInternalProps extends GlomoStandardCheckoutProps {
11
+ _analyticsTrackers?: CheckoutAnalyticsTrackers;
12
+ _skipOrderIdValidation?: boolean;
13
+ }
14
+ /**
15
+ * Widening the internal type to GlomoStandardCheckoutInternalProps for internal SDK use,
16
+ * then narrowing the public export to GlomoStandardCheckoutProps so merchants cannot
17
+ * pass internal-only props like _analyticsTrackers.
18
+ */
4
19
  export declare const GlomoStandardCheckout: React.ForwardRefExoticComponent<GlomoStandardCheckoutProps & React.RefAttributes<GlomoStandardCheckoutRef>>;
20
+ /**
21
+ * Internal reference - accepts GlomoStandardCheckoutInternalProps.
22
+ * Not re-exported from index.ts.
23
+ */
24
+ export declare const GlomoStandardCheckoutInternal: React.ForwardRefExoticComponent<GlomoStandardCheckoutInternalProps & React.RefAttributes<GlomoStandardCheckoutRef>>;
5
25
  //# sourceMappingURL=glomo-standard-checkout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"glomo-standard-checkout.d.ts","sourceRoot":"","sources":["../src/glomo-standard-checkout.tsx"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAiQ3G,eAAO,MAAM,qBAAqB,6GAEjC,CAAC"}
1
+ {"version":3,"file":"glomo-standard-checkout.d.ts","sourceRoot":"","sources":["../src/glomo-standard-checkout.tsx"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAC3G,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAGnE;;;;GAIG;AACH,MAAM,WAAW,kCAAmC,SAAQ,0BAA0B;IAClF,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC;AAmQD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAiD,KAAK,CAAC,yBAAyB,CAC9G,0BAA0B,GAAG,KAAK,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAC7E,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,6BAA6B,qHAEzC,CAAC"}
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  };
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.GlomoStandardCheckout = void 0;
37
+ exports.GlomoStandardCheckoutInternal = exports.GlomoStandardCheckout = void 0;
38
38
  const react_1 = __importStar(require("react"));
39
39
  const react_native_1 = require("react-native");
40
40
  const react_native_webview_1 = require("react-native-webview");
@@ -57,7 +57,7 @@ const validation_1 = require("./utils/validation");
57
57
  * @param ref - The ref for the component
58
58
  * @param devMode - Turn on to see all logs, warnings, and errors in the console. Off by default
59
59
  */
60
- function GlomoStandardCheckoutComponent({ server, publicKey, orderId, onPaymentSuccess, onPaymentFailure, onConnectionError, onPaymentTerminate, onSdkError, onBankTransferSubmitted, onPayViaBankCompleted, onPayViaBankBankConnectionSuccessful, onUserRefusedCameraPermissions, devMode = false, }, ref) {
60
+ function GlomoStandardCheckoutComponent({ server, publicKey, orderId, onPaymentSuccess, onPaymentFailure, onConnectionError, onPaymentTerminate, onSdkError, onBankTransferSubmitted, onPayViaBankCompleted, onPayViaBankBankConnectionSuccessful, onUserRefusedCameraPermissions, devMode = false, _analyticsTrackers, _skipOrderIdValidation, }, ref) {
61
61
  // Computing mockMode based on the publicKey prefix
62
62
  const mockMode = (0, react_1.useMemo)(() => {
63
63
  var _a;
@@ -81,7 +81,7 @@ function GlomoStandardCheckoutComponent({ server, publicKey, orderId, onPaymentS
81
81
  onPayViaBankBankConnectionSuccessful,
82
82
  onUserRefusedCameraPermissions,
83
83
  devMode,
84
- }, mockMode);
84
+ }, mockMode, { analyticsTrackers: _analyticsTrackers, _skipOrderIdValidation });
85
85
  // Exposing the start() and getStatus() methods via the ref
86
86
  (0, react_1.useImperativeHandle)(ref, () => ({
87
87
  start,
@@ -160,8 +160,19 @@ function GlomoStandardCheckoutComponent({ server, publicKey, orderId, onPaymentS
160
160
  </react_native_1.View>
161
161
  </ModalComponent>);
162
162
  }
163
+ /**
164
+ * Widening the internal type to GlomoStandardCheckoutInternalProps for internal SDK use,
165
+ * then narrowing the public export to GlomoStandardCheckoutProps so merchants cannot
166
+ * pass internal-only props like _analyticsTrackers.
167
+ */
163
168
  exports.GlomoStandardCheckout = (0, react_1.forwardRef)(GlomoStandardCheckoutComponent);
164
169
  exports.GlomoStandardCheckout.displayName = "GlomoStandardCheckout";
170
+ /**
171
+ * Internal reference - accepts GlomoStandardCheckoutInternalProps.
172
+ * Not re-exported from index.ts.
173
+ */
174
+ exports.GlomoStandardCheckoutInternal = (0, react_1.forwardRef)(GlomoStandardCheckoutComponent);
175
+ exports.GlomoStandardCheckoutInternal.displayName = "GlomoStandardCheckoutInternal";
165
176
  const styles = react_native_1.StyleSheet.create({
166
177
  modalContainer: {
167
178
  flex: 1,
@@ -0,0 +1,8 @@
1
+ /**
2
+ * GlomoSubscriptionsCheckout - thin wrapper around GlomoStandardCheckout
3
+ * that accepts a subscriptionId (sub_*) instead of an orderId (order_*).
4
+ */
5
+ import React from "react";
6
+ import { type GlomoSubscriptionsCheckoutProps, type GlomoSubscriptionsCheckoutRef } from "./types/subscriptions-checkout";
7
+ export declare const GlomoSubscriptionsCheckout: React.ForwardRefExoticComponent<GlomoSubscriptionsCheckoutProps & React.RefAttributes<GlomoSubscriptionsCheckoutRef>>;
8
+ //# sourceMappingURL=glomo-subscriptions-checkout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glomo-subscriptions-checkout.d.ts","sourceRoot":"","sources":["../src/glomo-subscriptions-checkout.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA6D,MAAM,OAAO,CAAC;AAIlF,OAAO,EACH,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EACrC,MAAM,gCAAgC,CAAC;AAkExC,eAAO,MAAM,0BAA0B,uHAEtC,CAAC"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * GlomoSubscriptionsCheckout - thin wrapper around GlomoStandardCheckout
4
+ * that accepts a subscriptionId (sub_*) instead of an orderId (order_*).
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.GlomoSubscriptionsCheckout = void 0;
41
+ const react_1 = __importStar(require("react"));
42
+ const glomo_standard_checkout_1 = require("./glomo-standard-checkout");
43
+ const analytics_1 = require("./utils/analytics");
44
+ const validation_1 = require("./utils/validation");
45
+ function GlomoSubscriptionsCheckoutComponent(props, ref) {
46
+ const { subscriptionId: rawSubscriptionId, onSdkError, devMode = false, ...rest } = props;
47
+ const innerRef = (0, react_1.useRef)(null);
48
+ const onSdkErrorRef = (0, react_1.useRef)(onSdkError);
49
+ onSdkErrorRef.current = onSdkError;
50
+ const subscriptionId = rawSubscriptionId.trim();
51
+ /** Validating subscriptionId - firing onSdkError via useEffect to avoid side effects during render */
52
+ const validationError = (() => {
53
+ if (subscriptionId.length === 0) {
54
+ return "subscriptionId must not be empty";
55
+ }
56
+ if (!subscriptionId.startsWith("sub_")) {
57
+ return "subscriptionId must start with 'sub_'";
58
+ }
59
+ return null;
60
+ })();
61
+ (0, react_1.useEffect)(() => {
62
+ if (validationError) {
63
+ (0, validation_1.safeCallback)(onSdkErrorRef.current, [[{ type: "validation_error", message: validationError }]], "onSdkError", devMode);
64
+ }
65
+ }, [validationError, devMode]);
66
+ (0, react_1.useImperativeHandle)(ref, () => ({
67
+ start: () => {
68
+ var _a, _b;
69
+ if (validationError) {
70
+ return false;
71
+ }
72
+ return (_b = (_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.start()) !== null && _b !== void 0 ? _b : false;
73
+ },
74
+ getStatus: () => {
75
+ var _a, _b;
76
+ return (_b = (_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.getStatus()) !== null && _b !== void 0 ? _b : "ready";
77
+ },
78
+ }));
79
+ if (validationError) {
80
+ return null;
81
+ }
82
+ return (<glomo_standard_checkout_1.GlomoStandardCheckoutInternal ref={innerRef} {...rest} orderId={subscriptionId} onSdkError={onSdkError} devMode={devMode} _analyticsTrackers={analytics_1.subscriptionCheckoutTrackers} _skipOrderIdValidation={true}/>);
83
+ }
84
+ exports.GlomoSubscriptionsCheckout = (0, react_1.forwardRef)(GlomoSubscriptionsCheckoutComponent);
85
+ exports.GlomoSubscriptionsCheckout.displayName = "GlomoSubscriptionsCheckout";