@glomopay/react-native-sdk 2.0.1 โ 3.0.1
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/CHANGELOG.md +64 -0
- package/README.md +261 -314
- package/lib/config/base.d.ts +17 -11
- package/lib/config/base.d.ts.map +1 -1
- package/lib/config/base.js +19 -7
- package/lib/config/segment.js +3 -3
- package/lib/glomo-checkout.d.ts +8 -0
- package/lib/glomo-checkout.d.ts.map +1 -0
- package/lib/glomo-checkout.js +69 -0
- package/lib/glomo-lrs-checkout.d.ts.map +1 -1
- package/lib/glomo-lrs-checkout.js +9 -9
- package/lib/glomo-standard-checkout.d.ts +5 -0
- package/lib/glomo-standard-checkout.d.ts.map +1 -0
- package/lib/glomo-standard-checkout.js +218 -0
- package/lib/index.d.ts +5 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -5
- package/lib/injections/index.d.ts +1 -0
- package/lib/injections/index.d.ts.map +1 -1
- package/lib/injections/index.js +2 -0
- package/lib/injections/webview-flow.injection.d.ts.map +1 -1
- package/lib/injections/webview-flow.injection.js +106 -69
- package/lib/injections/webview-main.injection.d.ts.map +1 -1
- package/lib/injections/webview-main.injection.js +112 -77
- package/lib/injections/webview-standard.injection.d.ts +3 -0
- package/lib/injections/webview-standard.injection.d.ts.map +1 -0
- package/lib/injections/webview-standard.injection.js +214 -0
- package/lib/services/order-type-fetcher.d.ts +28 -0
- package/lib/services/order-type-fetcher.d.ts.map +1 -0
- package/lib/services/order-type-fetcher.js +99 -0
- package/lib/types/checkout.d.ts +53 -0
- package/lib/types/checkout.d.ts.map +1 -0
- package/lib/types/checkout.js +3 -0
- package/lib/types/standard-checkout.d.ts +40 -0
- package/lib/types/standard-checkout.d.ts.map +1 -0
- package/lib/types/standard-checkout.js +3 -0
- package/lib/use-glomo-checkout.d.ts +24 -0
- package/lib/use-glomo-checkout.d.ts.map +1 -0
- package/lib/use-glomo-checkout.js +182 -0
- package/lib/use-lrs-checkout.d.ts +9 -4
- package/lib/use-lrs-checkout.d.ts.map +1 -1
- package/lib/use-lrs-checkout.js +91 -93
- package/lib/use-standard-checkout.d.ts +65 -0
- package/lib/use-standard-checkout.d.ts.map +1 -0
- package/lib/use-standard-checkout.js +832 -0
- package/lib/utils/analytics.d.ts +102 -1
- package/lib/utils/analytics.d.ts.map +1 -1
- package/lib/utils/analytics.js +294 -21
- package/lib/utils/device-compliance.js +3 -3
- package/lib/utils/validation.d.ts.map +1 -1
- package/lib/utils/validation.js +7 -6
- package/package.json +3 -2
- package/src/config/base.ts +36 -17
- package/src/config/segment.ts +3 -3
- package/src/glomo-checkout.tsx +73 -0
- package/src/glomo-lrs-checkout.tsx +13 -10
- package/src/glomo-standard-checkout.tsx +324 -0
- package/src/index.ts +13 -7
- package/src/injections/index.ts +2 -0
- package/src/injections/webview-flow.injection.ts +106 -69
- package/src/injections/webview-main.injection.ts +112 -77
- package/src/injections/webview-standard.injection.ts +211 -0
- package/src/services/order-type-fetcher.ts +86 -0
- package/src/types/checkout.ts +65 -0
- package/src/types/standard-checkout.ts +49 -0
- package/src/use-glomo-checkout.tsx +228 -0
- package/src/use-lrs-checkout.tsx +115 -111
- package/src/use-standard-checkout.tsx +1185 -0
- package/src/utils/analytics.ts +431 -22
- package/src/utils/device-compliance.ts +3 -3
- package/src/utils/validation.ts +7 -8
package/README.md
CHANGED
|
@@ -7,130 +7,121 @@ Official React Native SDK for integrating GlomoPay payment checkout flows into y
|
|
|
7
7
|
|
|
8
8
|
## โจ Features
|
|
9
9
|
|
|
10
|
-
- ๐ฑ **Cross-
|
|
11
|
-
- ๐ท **TypeScript
|
|
12
|
-
- โก **
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
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
|
|
16
19
|
|
|
17
20
|
## ๐ Prerequisites
|
|
18
21
|
|
|
19
|
-
Before using this SDK, you need:
|
|
20
|
-
|
|
21
22
|
- API credentials (Public Key) from your GlomoPay dashboard
|
|
23
|
+
- An order ID created via the GlomoPay API
|
|
22
24
|
|
|
23
25
|
## ๐ ๏ธ System Requirements
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
| Requirement | Version |
|
|
28
|
+
| ---------------------- | ------------ |
|
|
29
|
+
| Node.js | >= 16.0.0 |
|
|
30
|
+
| npm | >= 8.0.0 |
|
|
31
|
+
| React | >= 17.0.0 |
|
|
32
|
+
| React Native | >= 0.68.0 |
|
|
33
|
+
| react-native-webview | ^13.0.0 |
|
|
34
|
+
| jail-monkey (optional) | ^2.6.0 |
|
|
29
35
|
|
|
30
|
-
##
|
|
36
|
+
## โ ๏ธ Breaking Changes (v3)
|
|
31
37
|
|
|
32
|
-
|
|
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`)
|
|
33
41
|
|
|
34
|
-
For
|
|
42
|
+
For the full list of changes and migration details, see [CHANGELOG.md](./CHANGELOG.md) and [Migration from v2](#-migration-from-v2).
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
npm install react-native-webview
|
|
38
|
-
```
|
|
44
|
+
## ๐ฆ Installation
|
|
39
45
|
|
|
40
|
-
|
|
46
|
+
### React Native CLI
|
|
41
47
|
|
|
42
48
|
```bash
|
|
43
|
-
npm install @glomopay/react-native-sdk
|
|
49
|
+
npm install @glomopay/react-native-sdk react-native-webview
|
|
50
|
+
cd ios && pod install
|
|
44
51
|
```
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
For enhanced device security compliance (rooted/jailbroken device detection), we HIGHLY recommend installing the peer dependency `jail-monkey`:
|
|
53
|
+
### Expo
|
|
49
54
|
|
|
50
55
|
```bash
|
|
51
|
-
|
|
56
|
+
npx expo install @glomopay/react-native-sdk react-native-webview
|
|
52
57
|
```
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
### ๐ง 2. Expo Projects
|
|
59
|
+
### Recommended: Device Security Compliance
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
For rooted/jailbroken device detection (strongly recommended for regulated flows):
|
|
59
62
|
|
|
60
63
|
```bash
|
|
61
|
-
|
|
62
|
-
npx expo install @glomopay/react-native-sdk
|
|
64
|
+
npm install jail-monkey
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
For Expo Go limitations, see [Expo documentation](https://docs.expo.dev/workflow/customizing/).
|
|
67
|
+
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
68
|
|
|
69
69
|
## ๐ Quick Start
|
|
70
70
|
|
|
71
|
-
Before start the checkout flow, you'll need to create an LRS order using other Glomo SDKs and obtain the Order ID (Alphanumeric, starts with `order_`).
|
|
72
|
-
|
|
73
|
-
### Breaking Changes (latest)
|
|
74
|
-
|
|
75
|
-
- `server` no longer accepts a custom URL string. It now accepts one of: `"prod"`, `"staging"`.
|
|
76
|
-
- `educationURL` has been removed from the public API. The SDK now manages any educational content behavior internally.
|
|
77
|
-
|
|
78
|
-
### 1. Import the SDK
|
|
79
|
-
|
|
80
71
|
```tsx
|
|
72
|
+
import React, { useRef } from "react";
|
|
73
|
+
import { View, Button } from "react-native";
|
|
81
74
|
import {
|
|
82
|
-
|
|
83
|
-
type
|
|
75
|
+
GlomoCheckout,
|
|
76
|
+
type GlomoCheckoutRef,
|
|
77
|
+
type GlomoCheckoutPayload,
|
|
84
78
|
type SdkError,
|
|
85
|
-
} from
|
|
86
|
-
```
|
|
79
|
+
} from "@glomopay/react-native-sdk";
|
|
87
80
|
|
|
88
|
-
|
|
81
|
+
export default function PaymentScreen() {
|
|
82
|
+
const checkoutRef = useRef<GlomoCheckoutRef>(null);
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
import { View } from 'react-native';
|
|
93
|
-
import {
|
|
94
|
-
GlomoLrsCheckout,
|
|
95
|
-
type GlomoLrsCheckoutRef,
|
|
96
|
-
} from '@glomopay/react-native-sdk';
|
|
97
|
-
|
|
98
|
-
function CheckoutScreen()
|
|
99
|
-
{
|
|
100
|
-
const [orderId, setOrderId] = useState('YOUR_ORDER_ID');
|
|
101
|
-
const checkoutRef = useRef<GlomoLrsCheckoutRef>(null);
|
|
102
|
-
|
|
103
|
-
const startLrsCheckout = () => {
|
|
104
|
-
const started = checkoutRef.current?.start();
|
|
84
|
+
const handlePay = async () => {
|
|
85
|
+
const started = await checkoutRef.current?.start();
|
|
105
86
|
if (!started) {
|
|
106
|
-
|
|
107
|
-
console.log('Checkout could not be started. Current status:', status);
|
|
87
|
+
console.log("Checkout could not start - check onSdkError for details");
|
|
108
88
|
}
|
|
109
89
|
};
|
|
110
90
|
|
|
111
91
|
return (
|
|
112
|
-
<View>
|
|
113
|
-
<
|
|
92
|
+
<View style={{ flex: 1 }}>
|
|
93
|
+
<Button title="Pay Now" onPress={handlePay} />
|
|
94
|
+
|
|
95
|
+
<GlomoCheckout
|
|
114
96
|
ref={checkoutRef}
|
|
115
|
-
publicKey=
|
|
116
|
-
orderId=
|
|
117
|
-
onPaymentSuccess={(payload) => {
|
|
118
|
-
console.log(
|
|
119
|
-
|
|
97
|
+
publicKey="live_pk_abc123"
|
|
98
|
+
orderId="order_xyz789"
|
|
99
|
+
onPaymentSuccess={(payload: GlomoCheckoutPayload) => {
|
|
100
|
+
console.log("Payment success:", payload.paymentId);
|
|
101
|
+
}}
|
|
102
|
+
onPaymentFailure={(payload: GlomoCheckoutPayload) => {
|
|
103
|
+
console.log("Payment failed:", payload.paymentId);
|
|
120
104
|
}}
|
|
121
|
-
|
|
122
|
-
console.log(
|
|
123
|
-
// Handle failed payment
|
|
105
|
+
onPaymentTerminate={() => {
|
|
106
|
+
console.log("User dismissed checkout");
|
|
124
107
|
}}
|
|
125
108
|
onConnectionError={(error) => {
|
|
126
|
-
console.log(
|
|
127
|
-
|
|
109
|
+
console.log("Connection error:", error);
|
|
110
|
+
}}
|
|
111
|
+
onBankTransferSubmitted={(payload) => {
|
|
112
|
+
console.log("Bank transfer submitted:", payload?.transactionReference);
|
|
128
113
|
}}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
114
|
+
onPayViaBankCompleted={(payload) => {
|
|
115
|
+
console.log("Pay via bank completed:", payload.status);
|
|
116
|
+
}}
|
|
117
|
+
onPayViaBankBankConnectionSuccessful={(payload) => {
|
|
118
|
+
console.log("Bank connected:", payload?.bankName);
|
|
119
|
+
}}
|
|
120
|
+
onUserRefusedCameraPermissions={() => {
|
|
121
|
+
console.log("User refused camera - cannot proceed with bank authentication");
|
|
122
|
+
}}
|
|
123
|
+
onSdkError={(errors: SdkError[]) => {
|
|
124
|
+
errors.forEach((e) => console.error(e.type, e.message, e.field));
|
|
134
125
|
}}
|
|
135
126
|
/>
|
|
136
127
|
</View>
|
|
@@ -140,315 +131,271 @@ function CheckoutScreen()
|
|
|
140
131
|
|
|
141
132
|
## ๐ API Reference
|
|
142
133
|
|
|
143
|
-
###
|
|
144
|
-
|
|
145
|
-
#### Props
|
|
134
|
+
### GlomoCheckout Component
|
|
146
135
|
|
|
147
|
-
|
|
148
|
-
|------|------|----------|-------------|
|
|
149
|
-
| `server` | `"prod" \| "staging"` | No | (For development use ONLY) SDK server environment selector. Defaults to `"prod"` when omitted. |
|
|
150
|
-
| `publicKey` | `string` | Yes | Your public key. If it starts with `test_`, mock mode will be enabled automatically. Otherwise, live mode is used. |
|
|
151
|
-
| `orderId` | `string` | Yes | The order ID for this transaction. Must start with `order_` |
|
|
152
|
-
| `onPaymentSuccess` | `(payload: GlomoLrsCheckoutPayload) => void` | Yes | Callback function called when the payment is successful |
|
|
153
|
-
| `onPaymentFailure` | `(payload: GlomoLrsCheckoutPayload) => void` | Yes | Callback function called when the payment fails |
|
|
154
|
-
| `onConnectionError` | `(error: unknown) => void` | No | Will be called on network connection problems. The checkout modal will automatically close before this is triggered. |
|
|
155
|
-
| `onPaymentTerminate` | `() => void` | No | Callback called when checkout is terminated. Triggered when the `checkout.closed` event is received from the WebView or when the user dismisses the modal (iOS swipe down) or presses the back button (Android) |
|
|
156
|
-
| `onSdkError` | `(errors: SdkError[]) => void` | No | Callback for SDK validation errors and configuration issues. Receives an array of `SdkError` objects when validation fails. |
|
|
157
|
-
| `devMode` | `boolean` | No | Enable debug logging (default: `false`) |
|
|
158
|
-
| `visible` | `boolean` | No | Control modal visibility manually (advanced usage only). It is HIGHLY recommended to not use this prop directly. |
|
|
159
|
-
|
|
160
|
-
### Ref Methods
|
|
136
|
+
The unified checkout component. Place it in your render tree and control it via a ref.
|
|
161
137
|
|
|
162
138
|
```tsx
|
|
163
|
-
|
|
164
|
-
start: () => boolean; // Starts the checkout flow. Returns true if started, false if it cannot be started.
|
|
165
|
-
getStatus: () => LrsCheckoutStatus; // Returns the current checkout status
|
|
166
|
-
}
|
|
139
|
+
<GlomoCheckout ref={checkoutRef} {...props} />
|
|
167
140
|
```
|
|
168
141
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
142
|
+
#### Props (`GlomoCheckoutProps`)
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Required | Description |
|
|
145
|
+
| -------------------------------- | ----------------------------------------------- | -------- | ------------------------------------------------------------------- |
|
|
146
|
+
| `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_`) |
|
|
148
|
+
| `onPaymentSuccess` | `(payload: GlomoCheckoutPayload) => void` | Yes | Called when payment succeeds |
|
|
149
|
+
| `onPaymentFailure` | `(payload: GlomoCheckoutPayload) => void` | Yes | Called when payment fails |
|
|
150
|
+
| `onConnectionError` | `(error: unknown) => void` | No | Called on network/connection errors |
|
|
151
|
+
| `onPaymentTerminate` | `() => void` | No | Called when user dismisses checkout (back button or swipe) |
|
|
152
|
+
| `onSdkError` | `(errors: SdkError[]) => void` | No | Called on validation errors or device compliance failures |
|
|
153
|
+
| `onBankTransferSubmitted` | `(payload: GlomoBankTransferPayload \| null \| undefined) => void` | No | Called when user submits bank transfer details |
|
|
154
|
+
| `onPayViaBankCompleted` | `(payload: { status: string }) => void` | No | Called when pay via bank flow completes |
|
|
155
|
+
| `onPayViaBankBankConnectionSuccessful` | `(payload: GlomoPayViaBankConnectionPayload \| null \| undefined) => void` | No | Called when bank connection is established during pay via bank flow |
|
|
156
|
+
| `onUserRefusedCameraPermissions` | `() => void` | No | Called when user denies camera access needed for bank authentication |
|
|
157
|
+
|
|
158
|
+
#### Ref Methods (`GlomoCheckoutRef`)
|
|
159
|
+
|
|
160
|
+
| Method | Signature | Description |
|
|
161
|
+
| ------------ | ------------------------ | --------------------------------------------------------------------------------------------------------- |
|
|
162
|
+
| `start()` | `() => Promise<boolean>` | Validates inputs, and opens the checkout modal. Resolves `true` if successful, `false` otherwise. |
|
|
163
|
+
| `getStatus()`| `() => CheckoutStatus` | Returns the current checkout status. |
|
|
164
|
+
|
|
165
|
+
#### CheckoutStatus
|
|
166
|
+
|
|
167
|
+
| Status | Description |
|
|
168
|
+
| -------------------------- | -------------------------------------------------------------- |
|
|
169
|
+
| `ready` | Initial state - checkout can be started |
|
|
170
|
+
| `payment_in_progress` | Checkout modal is open, user is interacting |
|
|
171
|
+
| `payment_successful` | Payment completed successfully. Cannot restart with same order |
|
|
172
|
+
| `payment_failed` | Payment failed. Can retry with same order |
|
|
173
|
+
| `payment_cancelled` | User dismissed checkout mid-flow. Can retry |
|
|
174
|
+
| `bank_transfer_submitted` | User submitted bank transfer details |
|
|
175
|
+
| `pay_via_bank_completed` | Pay via bank flow completed |
|
|
176
|
+
|
|
177
|
+
### Type Definitions
|
|
178
|
+
|
|
179
|
+
#### GlomoCheckoutPayload
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
interface GlomoCheckoutPayload {
|
|
183
|
+
orderId: string;
|
|
184
|
+
paymentId: string;
|
|
185
|
+
signature: string;
|
|
179
186
|
}
|
|
180
|
-
|
|
181
|
-
// Check status
|
|
182
|
-
const currentStatus = checkoutRef.current?.getStatus();
|
|
183
187
|
```
|
|
184
188
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
- Or if the payment failed or timed-out (`"payment_failed"` status)
|
|
193
|
-
- After an LRS checkout for an `orderId` is successful, further calls to the `start()` method will return false, and will not re-trigger an LRS checkout (`"payment_successful"` status)
|
|
194
|
-
- Changing the `orderId`/`publicKey` props resets the flow, and `start()` can be triggered again
|
|
195
|
-
|
|
196
|
-
#### `GlomoLrsCheckoutPayload`
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
interface GlomoLrsCheckoutPayload {
|
|
201
|
-
orderId: string; // Order identifier (e.g., "order_abc123")
|
|
202
|
-
paymentId: string; // Payment id from GlomoPay
|
|
203
|
-
signature: string; // Signature for verification
|
|
189
|
+
#### GlomoBankTransferPayload
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
interface GlomoBankTransferPayload {
|
|
193
|
+
orderId: string;
|
|
194
|
+
senderAccountNumber: string;
|
|
195
|
+
transactionReference: string;
|
|
204
196
|
}
|
|
205
197
|
```
|
|
206
198
|
|
|
207
|
-
|
|
199
|
+
#### GlomoPayViaBankConnectionPayload
|
|
208
200
|
|
|
209
|
-
|
|
201
|
+
```ts
|
|
202
|
+
interface GlomoPayViaBankConnectionPayload {
|
|
203
|
+
bankIdentifier: string;
|
|
204
|
+
cooldownPeriodInMinutes: number;
|
|
205
|
+
bankName: string;
|
|
206
|
+
bankImageSrc: string;
|
|
207
|
+
bankImageAlt: string;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
#### SdkError
|
|
212
212
|
|
|
213
|
-
```
|
|
213
|
+
```ts
|
|
214
214
|
interface SdkError {
|
|
215
215
|
type: "validation_error" | "device_forbidden";
|
|
216
216
|
message: string;
|
|
217
|
-
field?:
|
|
217
|
+
field?: string;
|
|
218
218
|
}
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
221
|
+
## ๐ฐ Bank Transfer Support
|
|
222
|
+
|
|
223
|
+
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
224
|
|
|
225
|
-
**Example:**
|
|
226
225
|
```tsx
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (error.field) {
|
|
232
|
-
console.error(`Field: ${error.field}`);
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
// Handle validation errors appropriately
|
|
236
|
-
}}
|
|
237
|
-
// ... other props
|
|
238
|
-
/>
|
|
226
|
+
onBankTransferSubmitted={(payload) => {
|
|
227
|
+
// payload may be null/undefined if the checkout page omits it
|
|
228
|
+
console.log("Transfer ref:", payload?.transactionReference);
|
|
229
|
+
}}
|
|
239
230
|
```
|
|
240
231
|
|
|
241
|
-
|
|
232
|
+
The checkout status transitions to `bank_transfer_submitted`.
|
|
242
233
|
|
|
243
|
-
|
|
234
|
+
## ๐ฆ Pay via Bank Support
|
|
244
235
|
|
|
245
|
-
The SDK
|
|
236
|
+
The SDK fires `onPayViaBankCompleted` when the pay-via-bank journey completes:
|
|
246
237
|
|
|
247
238
|
```tsx
|
|
248
|
-
|
|
249
|
-
|
|
239
|
+
onPayViaBankCompleted={(payload) => {
|
|
240
|
+
// payload.status - e.g. "success", "failed", "unknown"
|
|
241
|
+
console.log("Pay via bank status:", payload.status);
|
|
242
|
+
}}
|
|
250
243
|
```
|
|
251
244
|
|
|
252
|
-
|
|
245
|
+
The checkout status transitions to `pay_via_bank_completed`. The SDK deduplicates this event internally - the callback fires only once per checkout session.
|
|
246
|
+
|
|
247
|
+
Additionally, `onPayViaBankBankConnectionSuccessful` fires when a bank account is successfully connected when initiating a pay-via-bank checkout, before the actual payment completes. This is informational only - it does not change the checkout status. Can be used to show a "bank connected" confirmation UI if desirable, while the payment continues in the background:
|
|
253
248
|
|
|
254
|
-
|
|
249
|
+
```tsx
|
|
250
|
+
onPayViaBankBankConnectionSuccessful={(payload) => {
|
|
251
|
+
// payload may be null/undefined if the checkout page omits it
|
|
252
|
+
console.log("Connected to:", payload?.bankName);
|
|
253
|
+
console.log("Cooldown:", payload?.cooldownPeriodInMinutes, "minutes");
|
|
254
|
+
}}
|
|
255
|
+
```
|
|
255
256
|
|
|
256
|
-
|
|
257
|
-
|--------|-------------|
|
|
258
|
-
| `"ready"` | Checkout is ready to be started |
|
|
259
|
-
| `"payment_in_progress"` | Checkout flow is active and ongoing |
|
|
260
|
-
| `"payment_successful"` | Payment completed successfully |
|
|
261
|
-
| `"payment_failed"` | Payment failed (`glomoLrsCheckoutRef.current?.start()` can be reused with the same `orderId`) |
|
|
262
|
-
| `"payment_cancelled"` | User cancelled the checkout midway (`glomoLrsCheckoutRef.current?.start()` can be reused with the same `orderId`) |
|
|
257
|
+
## ๐ท Camera Permissions for bank authentication
|
|
263
258
|
|
|
264
|
-
|
|
259
|
+
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.
|
|
265
260
|
|
|
261
|
+
### Android
|
|
262
|
+
|
|
263
|
+
Add to `android/app/src/main/AndroidManifest.xml`:
|
|
264
|
+
|
|
265
|
+
```xml
|
|
266
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
266
267
|
```
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
268
|
+
|
|
269
|
+
### iOS
|
|
270
|
+
|
|
271
|
+
Add to `ios/<YourApp>/Info.plist`:
|
|
272
|
+
|
|
273
|
+
```xml
|
|
274
|
+
<key>NSCameraUsageDescription</key>
|
|
275
|
+
<string>Camera access is required for identity verification during checkout</string>
|
|
272
276
|
```
|
|
273
277
|
|
|
274
|
-
|
|
278
|
+
### Behavior
|
|
275
279
|
|
|
276
|
-
|
|
277
|
-
-
|
|
278
|
-
- Users can dismiss `GlomoLrsCheckout` component by swiping down
|
|
279
|
-
- `onPaymentTerminate` is called when modal is dismissed
|
|
280
|
+
- **Android**: SDK prompts the user via a native permission dialog. If denied, checkout closes and `onUserRefusedCameraPermissions` fires.
|
|
281
|
+
- **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.
|
|
280
282
|
|
|
281
|
-
|
|
282
|
-
- Checkout appears in full-screen mode
|
|
283
|
-
- Users can press the hardware back button to close the full-screen `GlomoLrsCheckout` component
|
|
284
|
-
- Back button triggers `onPaymentTerminate` and closes checkout
|
|
283
|
+
## ๐ฑ Platform Behavior
|
|
285
284
|
|
|
286
|
-
|
|
285
|
+
- **iOS**: Checkout opens as a `pageSheet` modal (swipe-down to dismiss). Dismissing fires `onPaymentTerminate`.
|
|
286
|
+
- **Android**: Checkout opens fullscreen. The hardware back button dismisses it and fires `onPaymentTerminate`.
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
## ๐ Device Security Compliance
|
|
289
289
|
|
|
290
|
-
|
|
291
|
-
**Solution**:
|
|
292
|
-
- Ensure `start()` is called via ref and check its return value
|
|
293
|
-
- If `start()` returns `false`, check the current status using `getStatus()`
|
|
294
|
-
- The checkout status must be `"ready"`, `"payment_cancelled"`, or `"payment_failed"` for `start()` to succeed
|
|
295
|
-
- The checkout status must NOT be `"payment_successful"` (successful payments cannot be restarted)
|
|
296
|
-
- **Device Security Compliance**: If peer dependency `jail-monkey` is installed and the device does not meet compliance requirements (the device is rooted/jailbroken), `start()` will return `false`. Check `onSdkError` callback for `device_forbidden` errors.
|
|
297
|
-
- However, if `jail-monkey` has not been installed, security compliance checks will be skipped.
|
|
298
|
-
- Check that `orderId` is provided and valid (must start with `order_`)
|
|
299
|
-
- If you're providing `server`, ensure it is one of: `"prod"`, `"staging"` (defaults to `"prod"` when omitted)
|
|
300
|
-
- Ensure `publicKey` is valid (must start with `live_`)
|
|
301
|
-
- Implement `onSdkError` callback to receive validation and device compliance error details
|
|
290
|
+
The SDK optionally integrates with `jail-monkey` to detect rooted (Android) or jailbroken (iOS) devices.
|
|
302
291
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
-
|
|
306
|
-
- Use custom dev client: `npx expo prebuild`
|
|
307
|
-
- Or use EAS Build for testing
|
|
292
|
+
- If `jail-monkey` is installed and the device is compromised: `start()` returns `false` and `onSdkError` fires with `type: "device_forbidden"`.
|
|
293
|
+
- If `jail-monkey` is installed and the device is clean: checkout proceeds normally.
|
|
294
|
+
- If `jail-monkey` is not installed: SDK logs a warning and proceeds without checking. This is not recommended for production deployments handling regulated transactions.
|
|
308
295
|
|
|
296
|
+
## ๐งช Mock Mode
|
|
309
297
|
|
|
310
|
-
|
|
298
|
+
The SDK infers mock mode from the `publicKey` prefix:
|
|
311
299
|
|
|
312
|
-
|
|
300
|
+
| Prefix | Mode | Environment |
|
|
301
|
+
| -------- | ----- | -------------------- |
|
|
302
|
+
| `live_` | Live | Production |
|
|
303
|
+
| `test_` | Mock | Test/sandbox |
|
|
304
|
+
| `mock_` | Mock | Test/sandbox |
|
|
313
305
|
|
|
314
|
-
|
|
315
|
-
<GlomoLrsCheckout
|
|
316
|
-
devMode={true}
|
|
317
|
-
// ... other props
|
|
318
|
-
/>
|
|
319
|
-
```
|
|
320
|
-
Remember to disable this in production.
|
|
306
|
+
Mock mode keys route to the sandbox backend. No real transactions are created.
|
|
321
307
|
|
|
322
|
-
|
|
308
|
+
## ๐ Connection Handling
|
|
323
309
|
|
|
324
|
-
|
|
310
|
+
The SDK detects connection errors from the WebView and fires `onConnectionError`:
|
|
325
311
|
|
|
326
|
-
-
|
|
327
|
-
-
|
|
312
|
+
- **iOS**: NSURLErrorDomain codes (-1001 timeout, -1003 host not found, -1004 connection refused, -1009 offline)
|
|
313
|
+
- **Android**: ERR_EMPTY_RESPONSE, ERR_CONNECTION_REFUSED, ERR_NAME_NOT_RESOLVED, ERR_INTERNET_DISCONNECTED, ERR_CONNECTION_TIMED_OUT, ERR_NETWORK_CHANGED
|
|
328
314
|
|
|
329
|
-
|
|
330
|
-
```tsx
|
|
331
|
-
// Mock mode (publicKey starts with "test_")
|
|
332
|
-
<GlomoLrsCheckout
|
|
333
|
-
publicKey="test_abc123..."
|
|
334
|
-
// ... other props
|
|
335
|
-
/>
|
|
336
|
-
|
|
337
|
-
// Live mode (publicKey does not start with "test_")
|
|
338
|
-
<GlomoLrsCheckout
|
|
339
|
-
publicKey="live_xyz789..."
|
|
340
|
-
// ... other props
|
|
341
|
-
/>
|
|
342
|
-
```
|
|
315
|
+
The checkout modal is automatically dismissed on connection errors.
|
|
343
316
|
|
|
344
|
-
|
|
317
|
+
## ๐ก๏ธ Input Validation
|
|
345
318
|
|
|
346
|
-
|
|
319
|
+
The SDK validates inputs before starting the checkout:
|
|
347
320
|
|
|
348
|
-
|
|
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. |
|
|
349
325
|
|
|
350
|
-
|
|
351
|
-
- Connection failures
|
|
352
|
-
- Internet unavailability
|
|
353
|
-
- DNS resolution failures
|
|
326
|
+
Validation failures fire `onSdkError` with `type: "validation_error"` and the relevant `field` name. `start()` returns `false`.
|
|
354
327
|
|
|
355
|
-
|
|
328
|
+
## ๐ Migration from v2
|
|
356
329
|
|
|
357
|
-
|
|
358
|
-
```tsx
|
|
359
|
-
<GlomoLrsCheckout
|
|
360
|
-
onConnectionError={(error) => {
|
|
361
|
-
// Handle connection/network errors
|
|
362
|
-
// The modal will be automatically closed before this callback is triggered
|
|
363
|
-
Alert.alert('Connection Error', 'Unable to connect to the GlomoPay servers. Please check your internet connection.');
|
|
364
|
-
}}
|
|
365
|
-
// ... other props
|
|
366
|
-
/>
|
|
367
|
-
```
|
|
330
|
+
v3 replaces the LRS-only `GlomoLrsCheckout` with a unified `GlomoCheckout`.
|
|
368
331
|
|
|
369
|
-
|
|
332
|
+
### Renamed Exports
|
|
370
333
|
|
|
371
|
-
|
|
334
|
+
| v2 | v3 |
|
|
335
|
+
| -------------------------- | ------------------------- |
|
|
336
|
+
| `GlomoLrsCheckout` | `GlomoCheckout` |
|
|
337
|
+
| `GlomoLrsCheckoutRef` | `GlomoCheckoutRef` |
|
|
338
|
+
| `GlomoLrsCheckoutProps` | `GlomoCheckoutProps` |
|
|
339
|
+
| `GlomoLrsCheckoutPayload` | `GlomoCheckoutPayload` |
|
|
340
|
+
| `GlomoLrsServer` | `GlomoServer` |
|
|
372
341
|
|
|
373
|
-
|
|
342
|
+
### Breaking Changes
|
|
374
343
|
|
|
375
|
-
|
|
344
|
+
- **`start()` is now async**: Returns `Promise<boolean>` instead of `boolean`. Update call sites to `await ref.current?.start()`.
|
|
345
|
+
- **New statuses**: `bank_transfer_submitted` and `pay_via_bank_completed` are new additions to `CheckoutStatus`.
|
|
346
|
+
- **New callbacks**: `onBankTransferSubmitted`, `onPayViaBankCompleted`, and `onUserRefusedCameraPermissions` are available.
|
|
376
347
|
|
|
377
|
-
|
|
378
|
-
npm install jail-monkey
|
|
379
|
-
```
|
|
348
|
+
For the full list of changes, see [CHANGELOG.md](./CHANGELOG.md).
|
|
380
349
|
|
|
381
|
-
|
|
350
|
+
## ๐จ Troubleshooting
|
|
382
351
|
|
|
383
|
-
|
|
384
|
-
- **Without `jail-monkey`:** The SDK skips automatic compliance checks, and allows checkout to proceed normally. Regulatory compliance would have to be enforced manually.
|
|
352
|
+
### `start()` returns `false`
|
|
385
353
|
|
|
386
|
-
|
|
354
|
+
Check `onSdkError` for details. Common causes:
|
|
355
|
+
- Invalid `publicKey` format (must start with `live_`, `mock_`, or `test_`)
|
|
356
|
+
- Invalid `orderId` format (must start with `order_`)
|
|
357
|
+
- Device is rooted/jailbroken (when `jail-monkey` is installed)
|
|
387
358
|
|
|
388
|
-
|
|
389
|
-
- Runs synchronously as the **first validation step** in the `start()` method
|
|
390
|
-
- Blocks checkout on non-compliant devices to meet regulatory requirements
|
|
391
|
-
- Works on both iOS and Android platforms
|
|
392
|
-
- Triggers the `onSdkError` callback with a `device_forbidden` error if a non-compliant device is detected
|
|
359
|
+
### Checkout opens but shows a blank screen
|
|
393
360
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
<GlomoLrsCheckout
|
|
397
|
-
onSdkError={(errors) => {
|
|
398
|
-
errors.forEach((error) => {
|
|
399
|
-
if (error.type === 'device_forbidden') {
|
|
400
|
-
Alert.alert(
|
|
401
|
-
'Device Unsafe',
|
|
402
|
-
'LRS checkout is not permitted on rooted or jailbroken devices per regulatory compliance requirements.'
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
}}
|
|
407
|
-
// ... other props
|
|
408
|
-
/>
|
|
409
|
-
```
|
|
361
|
+
- Verify network connectivity
|
|
362
|
+
- Check that the `publicKey` and `orderId` are valid
|
|
410
363
|
|
|
364
|
+
### Camera permission denied
|
|
411
365
|
|
|
412
|
-
|
|
366
|
+
- Ensure `AndroidManifest.xml` and `Info.plist` include camera permission declarations
|
|
367
|
+
- The `onUserRefusedCameraPermissions` callback will fire when the user denies
|
|
413
368
|
|
|
414
|
-
|
|
369
|
+
### `onPayViaBankCompleted` not firing
|
|
415
370
|
|
|
416
|
-
-
|
|
417
|
-
- **`orderId`**: Must start with `order_` and have a minimum length of 7 characters
|
|
418
|
-
- **`server`**: Optional. Must be one of `"prod"`, `"staging"` (defaults to `"prod"` when omitted)
|
|
371
|
+
- Ensure you are passing `onPayViaBankCompleted` as a prop to `GlomoCheckout`
|
|
419
372
|
|
|
420
|
-
|
|
421
|
-
- Device security compliance check (first, before any other validation)
|
|
422
|
-
- Input validation (publicKey, orderId, and server environment)
|
|
423
|
-
- Checkout URL validation (before building the final URL)
|
|
373
|
+
## ๐ Exports
|
|
424
374
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
375
|
+
```ts
|
|
376
|
+
// Component
|
|
377
|
+
export { GlomoCheckout } from "@glomopay/react-native-sdk";
|
|
378
|
+
|
|
379
|
+
// Types
|
|
380
|
+
export type {
|
|
381
|
+
GlomoCheckoutRef,
|
|
382
|
+
GlomoCheckoutProps,
|
|
383
|
+
GlomoCheckoutPayload,
|
|
384
|
+
CheckoutStatus,
|
|
385
|
+
GlomoBankTransferPayload,
|
|
386
|
+
GlomoPayViaBankConnectionPayload,
|
|
387
|
+
SdkError,
|
|
388
|
+
} from "@glomopay/react-native-sdk";
|
|
389
|
+
|
|
390
|
+
// Hook (advanced usage)
|
|
391
|
+
export { useGlomoCheckout } from "@glomopay/react-native-sdk";
|
|
439
392
|
```
|
|
440
393
|
|
|
441
394
|
## ๐ฌ Support
|
|
442
395
|
|
|
443
|
-
|
|
444
|
-
-
|
|
445
|
-
- ๐๏ธ Dashboard: https://dashboard.glomopay.com
|
|
446
|
-
|
|
447
|
-
### Contact Us
|
|
448
|
-
- โ๏ธ Email: developer@glomopay.com
|
|
449
|
-
- ๐๏ธ GitHub Issues: https://github.com/glomopay/glomopay-rn-sdk/issues
|
|
450
|
-
- ๐ Website: https://glomopay.com
|
|
396
|
+
- GitHub Issues: https://github.com/glomopay/glomopay-rn-sdk/issues
|
|
397
|
+
- Email: developer@glomopay.com
|
|
451
398
|
|
|
452
|
-
## License
|
|
399
|
+
## ๐ License
|
|
453
400
|
|
|
454
|
-
|
|
401
|
+
Apache-2.0. See [LICENSE](LICENSE) for details.
|