@grabjs/superapp-sdk 2.0.0-beta.38 → 2.0.0-beta.46
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/api-reference/api.json +5649 -6906
- package/dist/index.d.ts +65 -73
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -1
- package/skills/SKILL.md +394 -57
package/skills/SKILL.md
CHANGED
|
@@ -42,10 +42,11 @@ import { isSuccess, isError } from '@grabjs/superapp-sdk';
|
|
|
42
42
|
|
|
43
43
|
#### CDN (UMD Bundle)
|
|
44
44
|
|
|
45
|
-
If you are not using a bundler, load the SDK from a CDN and access it via the `SuperAppSDK` global
|
|
45
|
+
If you are not using a bundler, load the SDK from a CDN and access it via the `SuperAppSDK` global.
|
|
46
|
+
**Always pin to a specific version** (e.g., `@x.y.z`) — omitting the version always fetches the latest release, which may contain breaking changes.
|
|
46
47
|
|
|
47
48
|
```html
|
|
48
|
-
<script src="https://cdn.jsdelivr.net/npm/@grabjs/superapp-sdk/dist/index.js"></script>
|
|
49
|
+
<script src="https://cdn.jsdelivr.net/npm/@grabjs/superapp-sdk@x.y.z/dist/index.js"></script>
|
|
49
50
|
<script>
|
|
50
51
|
const { ContainerModule, ScopeModule, isSuccess, isError } = window.SuperAppSDK;
|
|
51
52
|
</script>
|
|
@@ -61,25 +62,20 @@ SDK methods communicate with the native Grab SuperApp via JSBridge. They only wo
|
|
|
61
62
|
Every SDK method returns a bridge response object with an HTTP-style `status_code`. SDK methods never throw — use type guards instead of try/catch.
|
|
62
63
|
|
|
63
64
|
```typescript
|
|
64
|
-
import {
|
|
65
|
+
import { ProfileModule, isSuccess, isError } from '@grabjs/superapp-sdk';
|
|
65
66
|
|
|
66
|
-
const
|
|
67
|
-
const response = await
|
|
67
|
+
const profile = new ProfileModule();
|
|
68
|
+
const response = await profile.fetchEmail();
|
|
68
69
|
|
|
69
70
|
if (isSuccess(response)) {
|
|
70
|
-
|
|
71
|
-
case 200:
|
|
72
|
-
console.log('QR Code scanned:', response.result.qrCode);
|
|
73
|
-
break;
|
|
74
|
-
case 204:
|
|
75
|
-
// operation completed with no content
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
71
|
+
console.log('Result:', response.result);
|
|
78
72
|
} else if (isError(response)) {
|
|
79
|
-
// response.error: string is guaranteed
|
|
80
73
|
switch (response.status_code) {
|
|
81
74
|
case 403:
|
|
82
|
-
// call IdentityModule.authorize() then ScopeModule.reloadScopes()
|
|
75
|
+
// Missing OAuth scope - call IdentityModule.authorize() then ScopeModule.reloadScopes()
|
|
76
|
+
break;
|
|
77
|
+
case 426:
|
|
78
|
+
// Grab app version too old - prompt user to update their app
|
|
83
79
|
break;
|
|
84
80
|
default:
|
|
85
81
|
console.error(`Error ${response.status_code}: ${response.error}`);
|
|
@@ -91,19 +87,79 @@ if (isSuccess(response)) {
|
|
|
91
87
|
|
|
92
88
|
The SDK uses HTTP-style status codes for all responses:
|
|
93
89
|
|
|
94
|
-
| Code | Type | Description
|
|
95
|
-
|
|
|
96
|
-
| `200` | OK | Request successful, `result` contains response data
|
|
97
|
-
| `204` | No Content | Request successful, no data returned
|
|
98
|
-
| `302` | Redirect | Redirect in progress
|
|
99
|
-
| `400` | Bad Request | Invalid request parameters
|
|
100
|
-
| `401` | Unauthorized | Authentication required
|
|
101
|
-
| `403` | Forbidden | Insufficient
|
|
102
|
-
| `404` | Not Found | Resource not found
|
|
103
|
-
| `424` | Failed Dependency | Underlying native request failed
|
|
104
|
-
| `426` | Upgrade Required |
|
|
105
|
-
| `500` | Internal Error | Unexpected SDK error
|
|
106
|
-
| `501` | Not Implemented |
|
|
90
|
+
| Code | Type | Description |
|
|
91
|
+
| :---- | :---------------- | :---------------------------------------------------------- |
|
|
92
|
+
| `200` | OK | Request successful, `result` contains response data |
|
|
93
|
+
| `204` | No Content | Request successful, no data returned |
|
|
94
|
+
| `302` | Redirect | Redirect in progress |
|
|
95
|
+
| `400` | Bad Request | Invalid request parameters |
|
|
96
|
+
| `401` | Unauthorized | Authentication required |
|
|
97
|
+
| `403` | Forbidden | Insufficient permission (see `@requiredOAuthScope` tag) |
|
|
98
|
+
| `404` | Not Found | Resource not found |
|
|
99
|
+
| `424` | Failed Dependency | Underlying native request failed |
|
|
100
|
+
| `426` | Upgrade Required | Grab app version too old (see `@minimumGrabAppVersion` tag) |
|
|
101
|
+
| `500` | Internal Error | Unexpected SDK error |
|
|
102
|
+
| `501` | Not Implemented | Outside Grab SuperApp environment |
|
|
103
|
+
|
|
104
|
+
### Handling 403 Forbidden
|
|
105
|
+
|
|
106
|
+
Methods tagged with `@requiredOAuthScope` require specific permissions. If the user hasn't granted the required scope, the method returns `403`. You must request authorization and reload scopes before retrying:
|
|
107
|
+
|
|
108
|
+
1. Call `IdentityModule.authorize()` to request the scope.
|
|
109
|
+
2. Call `ScopeModule.reloadScopes()` to refresh the SDK's internal permission state.
|
|
110
|
+
3. Retry the original method call.
|
|
111
|
+
|
|
112
|
+
#### Proactive Permission Checking
|
|
113
|
+
|
|
114
|
+
Proactively verify if the current session has the necessary permissions for a method using `ScopeModule.hasAccessTo()`:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const scope = new ScopeModule();
|
|
118
|
+
const hasAccess = await scope.hasAccessTo('LocationModule', 'getCoordinate');
|
|
119
|
+
|
|
120
|
+
if (isSuccess(hasAccess) && hasAccess.result) {
|
|
121
|
+
// Permission is available, safe to call the method
|
|
122
|
+
const location = await location.getCoordinate();
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import {
|
|
128
|
+
LocationModule,
|
|
129
|
+
IdentityModule,
|
|
130
|
+
ScopeModule,
|
|
131
|
+
isSuccess,
|
|
132
|
+
isError,
|
|
133
|
+
} from '@grabjs/superapp-sdk';
|
|
134
|
+
|
|
135
|
+
const location = new LocationModule();
|
|
136
|
+
const identity = new IdentityModule();
|
|
137
|
+
const scope = new ScopeModule();
|
|
138
|
+
|
|
139
|
+
const response = await location.getCoordinate();
|
|
140
|
+
|
|
141
|
+
if (isError(response) && response.status_code === 403) {
|
|
142
|
+
// 1. Request authorization for the required scope
|
|
143
|
+
const auth = await identity.authorize({
|
|
144
|
+
clientId: 'your-client-id',
|
|
145
|
+
redirectUri: 'https://your-app.com/callback',
|
|
146
|
+
scope: 'mobile.geolocation', // The scope defined in @requiredOAuthScope
|
|
147
|
+
environment: 'production',
|
|
148
|
+
responseMode: 'in_place',
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (isSuccess(auth)) {
|
|
152
|
+
// 2. Reload scopes so the new permission is available
|
|
153
|
+
await scope.reloadScopes();
|
|
154
|
+
|
|
155
|
+
// 3. Retry the original call
|
|
156
|
+
const retry = await location.getCoordinate();
|
|
157
|
+
if (isSuccess(retry)) {
|
|
158
|
+
console.log('Result:', retry.result);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
107
163
|
|
|
108
164
|
### Type Guards
|
|
109
165
|
|
|
@@ -161,6 +217,10 @@ You can also `await` a stream method directly to get its first value.
|
|
|
161
217
|
|
|
162
218
|
This guide covers the recommended setup for a MiniApp entry point — loading scopes, configuring the container UI, signalling readiness, and handling permissions.
|
|
163
219
|
|
|
220
|
+
### Demo App
|
|
221
|
+
|
|
222
|
+
The [demo](https://github.com/grab/superapp-sdk/tree/master/demo) folder contains two complete MiniApp samples demonstrating these integration patterns in action — one using CDN (vanilla HTML/JS) and one using React. Both implement the same user flow: OAuth authorization, user profile display, deferred location permissions, and checkout payment.
|
|
223
|
+
|
|
164
224
|
### Entry Point Setup
|
|
165
225
|
|
|
166
226
|
Run these steps once when your MiniApp initialises, before rendering any content.
|
|
@@ -249,6 +309,283 @@ if (isError(response)) {
|
|
|
249
309
|
}
|
|
250
310
|
```
|
|
251
311
|
|
|
312
|
+
### Analytics Event Tracking
|
|
313
|
+
|
|
314
|
+
Implement analytics events across your user journey to enable performance tracking and reporting. Events are sent via `ContainerModule.sendAnalyticsEvent()` and categorised by journey stage using `ContainerAnalyticsEventState`.
|
|
315
|
+
|
|
316
|
+
#### Required Events
|
|
317
|
+
|
|
318
|
+
##### Entry Point
|
|
319
|
+
|
|
320
|
+
###### Initiate action
|
|
321
|
+
|
|
322
|
+
Send the initiate event when users click call-to-action buttons to proceed:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import {
|
|
326
|
+
ContainerModule,
|
|
327
|
+
ContainerAnalyticsEventState,
|
|
328
|
+
isSuccess,
|
|
329
|
+
isError,
|
|
330
|
+
} from '@grabjs/superapp-sdk';
|
|
331
|
+
|
|
332
|
+
// Event names are plain strings — define your own constants
|
|
333
|
+
const EventName = {
|
|
334
|
+
INITIATE: 'INITIATE',
|
|
335
|
+
TRANSACT: 'TRANSACT',
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const containerModule = new ContainerModule();
|
|
339
|
+
|
|
340
|
+
// Send when the user clicks a call-to-action button
|
|
341
|
+
const response = await containerModule.sendAnalyticsEvent({
|
|
342
|
+
state: ContainerAnalyticsEventState.HOMEPAGE,
|
|
343
|
+
name: EventName.INITIATE,
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
if (isSuccess(response)) {
|
|
347
|
+
// Event sent successfully
|
|
348
|
+
} else if (isError(response)) {
|
|
349
|
+
console.error(`Failed to send event: ${response.error}`);
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
###### Custom interactions
|
|
354
|
+
|
|
355
|
+
Send custom events for additional interactions like banner clicks, category selections, or search queries. Include the `page` parameter and a descriptive event name:
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import {
|
|
359
|
+
ContainerModule,
|
|
360
|
+
ContainerAnalyticsEventState,
|
|
361
|
+
isSuccess,
|
|
362
|
+
isError,
|
|
363
|
+
} from '@grabjs/superapp-sdk';
|
|
364
|
+
|
|
365
|
+
const containerModule = new ContainerModule();
|
|
366
|
+
|
|
367
|
+
// Send for custom interactions such as banner clicks or category selections
|
|
368
|
+
const response = await containerModule.sendAnalyticsEvent({
|
|
369
|
+
state: ContainerAnalyticsEventState.CUSTOM,
|
|
370
|
+
name: 'BANNER_CLICK',
|
|
371
|
+
data: {
|
|
372
|
+
page: 'homepage',
|
|
373
|
+
banner_id: 'promo-summer-2024',
|
|
374
|
+
banner_position: 'top',
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
if (isSuccess(response)) {
|
|
379
|
+
// Event sent successfully
|
|
380
|
+
} else if (isError(response)) {
|
|
381
|
+
console.error(`Failed to send event: ${response.error}`);
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
##### Conversion Point
|
|
386
|
+
|
|
387
|
+
###### Transaction confirmation
|
|
388
|
+
|
|
389
|
+
Send the transaction confirmation event when users click the final confirmation button:
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import {
|
|
393
|
+
ContainerModule,
|
|
394
|
+
ContainerAnalyticsEventState,
|
|
395
|
+
isSuccess,
|
|
396
|
+
isError,
|
|
397
|
+
} from '@grabjs/superapp-sdk';
|
|
398
|
+
|
|
399
|
+
// Event names are plain strings — define your own constants
|
|
400
|
+
const EventName = {
|
|
401
|
+
INITIATE: 'INITIATE',
|
|
402
|
+
TRANSACT: 'TRANSACT',
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const containerModule = new ContainerModule();
|
|
406
|
+
|
|
407
|
+
// Send when the user clicks the final confirmation button
|
|
408
|
+
const response = await containerModule.sendAnalyticsEvent({
|
|
409
|
+
state: ContainerAnalyticsEventState.CHECKOUT_PAGE,
|
|
410
|
+
name: EventName.TRANSACT,
|
|
411
|
+
data: {
|
|
412
|
+
transaction_amount: 49.99,
|
|
413
|
+
transaction_currency: 'SGD',
|
|
414
|
+
transaction_id: 'TXN-2024-001234',
|
|
415
|
+
payment_method: 'grabpay',
|
|
416
|
+
item_count: 2,
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
if (isSuccess(response)) {
|
|
421
|
+
// Event sent successfully
|
|
422
|
+
} else if (isError(response)) {
|
|
423
|
+
console.error(`Failed to send event: ${response.error}`);
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
###### Custom interactions
|
|
428
|
+
|
|
429
|
+
Send custom events for checkout interactions like promo code applications or payment method selections:
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
import {
|
|
433
|
+
ContainerModule,
|
|
434
|
+
ContainerAnalyticsEventState,
|
|
435
|
+
isSuccess,
|
|
436
|
+
isError,
|
|
437
|
+
} from '@grabjs/superapp-sdk';
|
|
438
|
+
|
|
439
|
+
const containerModule = new ContainerModule();
|
|
440
|
+
|
|
441
|
+
// Send for custom checkout interactions such as promo code applications
|
|
442
|
+
const response = await containerModule.sendAnalyticsEvent({
|
|
443
|
+
state: ContainerAnalyticsEventState.CUSTOM,
|
|
444
|
+
name: 'PROMO_CODE_APPLIED',
|
|
445
|
+
data: {
|
|
446
|
+
page: 'checkout',
|
|
447
|
+
promo_code: 'SAVE20',
|
|
448
|
+
discount_amount: 10.0,
|
|
449
|
+
discount_type: 'percentage',
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
if (isSuccess(response)) {
|
|
454
|
+
// Event sent successfully
|
|
455
|
+
} else if (isError(response)) {
|
|
456
|
+
console.error(`Failed to send event: ${response.error}`);
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
##### Completion Point
|
|
461
|
+
|
|
462
|
+
###### Follow-up actions
|
|
463
|
+
|
|
464
|
+
Send custom events for post-transaction actions like downloading receipts or tracking orders:
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
import {
|
|
468
|
+
ContainerModule,
|
|
469
|
+
ContainerAnalyticsEventState,
|
|
470
|
+
isSuccess,
|
|
471
|
+
isError,
|
|
472
|
+
} from '@grabjs/superapp-sdk';
|
|
473
|
+
|
|
474
|
+
const containerModule = new ContainerModule();
|
|
475
|
+
|
|
476
|
+
// Send for post-transaction actions such as downloading a receipt
|
|
477
|
+
const response = await containerModule.sendAnalyticsEvent({
|
|
478
|
+
state: ContainerAnalyticsEventState.CUSTOM,
|
|
479
|
+
name: 'RECEIPT_DOWNLOAD',
|
|
480
|
+
data: {
|
|
481
|
+
page: 'completion',
|
|
482
|
+
transaction_id: 'TXN-2024-001234',
|
|
483
|
+
format: 'pdf',
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
if (isSuccess(response)) {
|
|
488
|
+
// Event sent successfully
|
|
489
|
+
} else if (isError(response)) {
|
|
490
|
+
console.error(`Failed to send event: ${response.error}`);
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
#### Best Practices
|
|
495
|
+
|
|
496
|
+
- Track system events automatically when users navigate to the corresponding pages.
|
|
497
|
+
- Always include required data fields for transaction events to enable accurate revenue tracking.
|
|
498
|
+
- Use descriptive names for custom events that clearly indicate the user action being tracked.
|
|
499
|
+
- Never include Personally Identifiable Information (PII) in event data.
|
|
500
|
+
|
|
501
|
+
### Checkout
|
|
502
|
+
|
|
503
|
+
The checkout flow is a two-step process: your backend first initializes a transaction using your partner credentials, then your frontend triggers the native payment interface using the response from your backend.
|
|
504
|
+
|
|
505
|
+
#### Step 1 — Initialize transaction on your backend
|
|
506
|
+
|
|
507
|
+
Before calling `CheckoutModule.triggerCheckout()`, you must create a transaction on your server by calling the [GrabPay API](https://developer.grab.com/docs/partner-apps/pages/developer-resources/payment/#create-transaction). This requires your `partnerID` and `partnerSecret` to generate an HMAC-SHA256 signature.
|
|
508
|
+
|
|
509
|
+
The API returns a payload containing `partnerTxID`, `request`, and `sessionID` — all three fields are required by the frontend.
|
|
510
|
+
|
|
511
|
+
#### Step 2 — Trigger checkout from your frontend
|
|
512
|
+
|
|
513
|
+
Pass the complete response from the Initialize Transaction API to `CheckoutModule.triggerCheckout()`:
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
import {
|
|
517
|
+
CheckoutModule,
|
|
518
|
+
IdentityModule,
|
|
519
|
+
ScopeModule,
|
|
520
|
+
isSuccess,
|
|
521
|
+
isError,
|
|
522
|
+
} from '@grabjs/superapp-sdk';
|
|
523
|
+
|
|
524
|
+
const checkout = new CheckoutModule();
|
|
525
|
+
const identity = new IdentityModule();
|
|
526
|
+
const scope = new ScopeModule();
|
|
527
|
+
|
|
528
|
+
async function processPayment() {
|
|
529
|
+
// 1. Ensure mobile.checkout scope is authorized
|
|
530
|
+
const authResponse = await identity.authorize({
|
|
531
|
+
clientId: 'your-client-id',
|
|
532
|
+
redirectUri: 'https://your-miniapp.example.com/callback',
|
|
533
|
+
scope: 'mobile.checkout',
|
|
534
|
+
environment: 'production',
|
|
535
|
+
responseMode: 'in_place',
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
if (isSuccess(authResponse)) {
|
|
539
|
+
await scope.reloadScopes();
|
|
540
|
+
} else if (isError(authResponse)) {
|
|
541
|
+
console.error('Authorization failed:', authResponse.error);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// 2. Fetch the initialized transaction payload from your backend
|
|
546
|
+
const response = await fetch('https://your-backend.example.com/init-transaction', {
|
|
547
|
+
method: 'POST',
|
|
548
|
+
headers: { 'Content-Type': 'application/json' },
|
|
549
|
+
body: JSON.stringify({ orderId: 'order-123' }),
|
|
550
|
+
});
|
|
551
|
+
const { partnerTxID, request, sessionID } = await response.json();
|
|
552
|
+
|
|
553
|
+
// 3. Trigger checkout with the backend response
|
|
554
|
+
const checkoutResult = await checkout.triggerCheckout({
|
|
555
|
+
partnerTxID,
|
|
556
|
+
request,
|
|
557
|
+
sessionID,
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
if (isSuccess(checkoutResult)) {
|
|
561
|
+
const { status, transactionID, errorCode, errorMessage } = checkoutResult.result;
|
|
562
|
+
|
|
563
|
+
if (status === 'success') {
|
|
564
|
+
console.log('Payment successful:', transactionID);
|
|
565
|
+
} else if (status === 'failure') {
|
|
566
|
+
console.error('Payment failed:', errorCode, errorMessage);
|
|
567
|
+
} else if (status === 'pending') {
|
|
568
|
+
console.log('Payment is processing:', transactionID);
|
|
569
|
+
} else if (status === 'userInitiatedCancel') {
|
|
570
|
+
console.log('User cancelled payment');
|
|
571
|
+
}
|
|
572
|
+
} else if (isError(checkoutResult)) {
|
|
573
|
+
console.error('Checkout error:', checkoutResult.error);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
#### Result status values
|
|
579
|
+
|
|
580
|
+
| Status | Description |
|
|
581
|
+
| :-------------------- | :----------------------------------------------------------------------------- |
|
|
582
|
+
| `success` | Payment completed successfully. `transactionID` is provided. |
|
|
583
|
+
| `failure` | Payment failed. `transactionID`, `errorCode`, and `errorMessage` are provided. |
|
|
584
|
+
| `pending` | Payment is still being processed. `transactionID` is provided. |
|
|
585
|
+
| `userInitiatedCancel` | User cancelled the payment. No other fields are present. |
|
|
586
|
+
|
|
587
|
+
For the complete API reference, see [CheckoutModule](https://grab.github.io/superapp-sdk/classes/CheckoutModule.html).
|
|
588
|
+
|
|
252
589
|
|
|
253
590
|
## API Reference
|
|
254
591
|
|
|
@@ -260,25 +597,25 @@ JSBridge module for accessing the device camera.
|
|
|
260
597
|
|
|
261
598
|
#### `CheckoutModule`
|
|
262
599
|
JSBridge module for triggering native payment flows.
|
|
263
|
-
- `triggerCheckout(request: Record<string, unknown>): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: { status: "success"; transactionID: string } | { errorCode: string; errorMessage: string; status: "failure"; transactionID: string } | { status: "pending"; transactionID: string } | { status: "userInitiatedCancel" }; status_code: 200 }>` — Triggers the native checkout flow for payment processing.
|
|
600
|
+
- `triggerCheckout(request: Record<string, unknown>): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: { status: "success"; transactionID: string } | { errorCode: string; errorMessage: string; status: "failure"; transactionID: string } | { status: "pending"; transactionID: string } | { status: "userInitiatedCancel" }; status_code: 200 }>` — Triggers the native checkout flow for payment processing. (**OAuth Scope:** mobile.checkout)
|
|
264
601
|
|
|
265
602
|
#### `ContainerModule`
|
|
266
603
|
JSBridge module for controlling the WebView container.
|
|
267
|
-
- `close(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
604
|
+
- `close(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Close the container and return to the previous screen.
|
|
268
605
|
- `getSessionParams(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: string; status_code: 200 }>` — Get the session parameters from the container.
|
|
269
|
-
- `hideBackButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
270
|
-
- `hideLoader(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
271
|
-
- `hideRefreshButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
606
|
+
- `hideBackButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Hide the back button on the container header.
|
|
607
|
+
- `hideLoader(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Hide the full-screen loading indicator.
|
|
608
|
+
- `hideRefreshButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Hide the refresh button on the container header.
|
|
272
609
|
- `isConnected(): Promise<{ result: { connected: boolean }; status_code: 200 } | { error: string; status_code: 404 }>` — Check if the web app is connected to the Grab SuperApp via JSBridge.
|
|
273
610
|
- `onContentLoaded(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: boolean; status_code: 200 }>` — Notify the Grab SuperApp that the page content has loaded.
|
|
274
611
|
- `onCtaTap(request: string): Promise<{ error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: boolean; status_code: 200 }>` — Notify the client that the user has tapped a call-to-action (CTA).
|
|
275
|
-
- `openExternalLink(request: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
276
|
-
- `sendAnalyticsEvent(request: { data?: Record<string, unknown>; name: string; state: string }): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
277
|
-
- `setBackgroundColor(request: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
278
|
-
- `setTitle(request: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
279
|
-
- `showBackButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
280
|
-
- `showLoader(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
281
|
-
- `showRefreshButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }
|
|
612
|
+
- `openExternalLink(request: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Open a link in the external browser.
|
|
613
|
+
- `sendAnalyticsEvent(request: { data?: Record<string, unknown>; name: string; state: string }): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Use this method to track user interactions and page transitions.
|
|
614
|
+
- `setBackgroundColor(request: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Set the background color of the container header.
|
|
615
|
+
- `setTitle(request: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Set the title of the container header.
|
|
616
|
+
- `showBackButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Show the back button on the container header.
|
|
617
|
+
- `showLoader(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Show the full-screen loading indicator.
|
|
618
|
+
- `showRefreshButton(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 }>` — Show the refresh button on the container header.
|
|
282
619
|
|
|
283
620
|
#### `DeviceModule`
|
|
284
621
|
JSBridge module for querying native device information.
|
|
@@ -304,17 +641,17 @@ JSBridge module for accessing device locale settings.
|
|
|
304
641
|
|
|
305
642
|
#### `LocationModule`
|
|
306
643
|
JSBridge module for accessing device location services.
|
|
307
|
-
- `getCoordinate(): Promise<{ error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: { latitude: number; longitude: number }; status_code: 200 } | { error: string; status_code: 424 }>` — Get the current geographic coordinates of the device.
|
|
308
|
-
- `getCountryCode(): Promise<{ status_code: 204 } | { error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: string; status_code: 200 } | { error: string; status_code: 424 }>` — Get the country code based on the device's current location.
|
|
309
|
-
- `observeLocationChange(): ObserveLocationChangeResponse` — Subscribe to location change updates from the device.
|
|
644
|
+
- `getCoordinate(): Promise<{ error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: { latitude: number; longitude: number }; status_code: 200 } | { error: string; status_code: 424 }>` — Get the current geographic coordinates of the device. (**OAuth Scope:** mobile.geolocation)
|
|
645
|
+
- `getCountryCode(): Promise<{ status_code: 204 } | { error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { result: string; status_code: 200 } | { error: string; status_code: 424 }>` — Get the country code based on the device's current location. (**OAuth Scope:** mobile.geolocation)
|
|
646
|
+
- `observeLocationChange(): ObserveLocationChangeResponse` — Subscribe to location change updates from the device. (**OAuth Scope:** mobile.geolocation)
|
|
310
647
|
|
|
311
648
|
#### `Logger`
|
|
312
649
|
Provides scoped logging for SDK modules.
|
|
313
650
|
|
|
314
651
|
#### `MediaModule`
|
|
315
652
|
JSBridge module for playing DRM-protected media content.
|
|
316
|
-
- `observePlayDRMContent(data: DRMContentConfig): ObserveDRMPlaybackResponse` — Observes DRM-protected media content playback events.
|
|
317
|
-
- `playDRMContent(data: DRMContentConfig): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { length: number; position: number; titleId: string; type: "START_PLAYBACK" | "PROGRESS_PLAYBACK" | "START_SEEK" | "STOP_SEEK" | "STOP_PLAYBACK" | "CLOSE_PLAYBACK" | "PAUSE_PLAYBACK" | "RESUME_PLAYBACK" | "FAST_FORWARD_PLAYBACK" | "REWIND_PLAYBACK" | "ERROR_PLAYBACK" | "CHANGE_VOLUME" }; status_code: 200 }>` — Plays DRM-protected media content in the native media player.
|
|
653
|
+
- `observePlayDRMContent(data: DRMContentConfig): ObserveDRMPlaybackResponse` — Observes DRM-protected media content playback events. (**OAuth Scope:** mobile.media)
|
|
654
|
+
- `playDRMContent(data: DRMContentConfig): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { length: number; position: number; titleId: string; type: "START_PLAYBACK" | "PROGRESS_PLAYBACK" | "START_SEEK" | "STOP_SEEK" | "STOP_PLAYBACK" | "CLOSE_PLAYBACK" | "PAUSE_PLAYBACK" | "RESUME_PLAYBACK" | "FAST_FORWARD_PLAYBACK" | "REWIND_PLAYBACK" | "ERROR_PLAYBACK" | "CHANGE_VOLUME" }; status_code: 200 }>` — Plays DRM-protected media content in the native media player. (**OAuth Scope:** mobile.media)
|
|
318
655
|
|
|
319
656
|
#### `NetworkModule`
|
|
320
657
|
JSBridge module for making network requests via the native bridge.
|
|
@@ -327,8 +664,8 @@ This navigates back in the native navigation stack.
|
|
|
327
664
|
|
|
328
665
|
#### `ProfileModule`
|
|
329
666
|
JSBridge module for accessing user profile information.
|
|
330
|
-
- `fetchEmail(): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 426 } | { result: { email: string }; status_code: 200 }>` — Fetches the user's email address from their Grab profile.
|
|
331
|
-
- `verifyEmail(request?: { email?: string; skipUserInput?: boolean }): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 426 } | { result: { email: string }; status_code: 200 }>` — Verifies the user's email address by triggering email capture bottom sheet and OTP verification.
|
|
667
|
+
- `fetchEmail(): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 426 } | { result: { email: string }; status_code: 200 }>` — Fetches the user's email address from their Grab profile. (**OAuth Scope:** mobile.profile | **Minimum Grab App Version:** Android: 5.399.0, iOS: 5.399.0)
|
|
668
|
+
- `verifyEmail(request?: { email?: string; skipUserInput?: boolean }): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 403 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 426 } | { result: { email: string }; status_code: 200 }>` — Verifies the user's email address by triggering email capture bottom sheet and OTP verification. (**OAuth Scope:** mobile.profile | **Minimum Grab App Version:** Android: 5.399.0, iOS: 5.399.0)
|
|
332
669
|
|
|
333
670
|
#### `ScopeModule`
|
|
334
671
|
JSBridge module for checking and refreshing API access permissions.
|
|
@@ -342,16 +679,16 @@ JSBridge module for controlling the native splash / Lottie loading screen.
|
|
|
342
679
|
|
|
343
680
|
#### `StorageModule`
|
|
344
681
|
JSBridge module for persisting key-value data to native storage.
|
|
345
|
-
- `getBoolean(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: boolean | null }; status_code: 200 }>` — Retrieves a boolean value from the native storage.
|
|
346
|
-
- `getDouble(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: number | null }; status_code: 200 }>` — Retrieves a double (floating point) value from the native storage.
|
|
347
|
-
- `getInt(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: number | null }; status_code: 200 }>` — Retrieves an integer value from the native storage.
|
|
348
|
-
- `getString(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: string | null }; status_code: 200 }>` — Retrieves a string value from the native storage.
|
|
349
|
-
- `remove(key: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Removes a single value from the native storage by key.
|
|
350
|
-
- `removeAll(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Removes all values from the native storage.
|
|
351
|
-
- `setBoolean(key: string, value: boolean): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores a boolean value in the native storage.
|
|
352
|
-
- `setDouble(key: string, value: number): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores a double (floating point) value in the native storage.
|
|
353
|
-
- `setInt(key: string, value: number): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores an integer value in the native storage.
|
|
354
|
-
- `setString(key: string, value: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores a string value in the native storage.
|
|
682
|
+
- `getBoolean(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: boolean | null }; status_code: 200 }>` — Retrieves a boolean value from the native storage. (**OAuth Scope:** mobile.storage)
|
|
683
|
+
- `getDouble(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: number | null }; status_code: 200 }>` — Retrieves a double (floating point) value from the native storage. (**OAuth Scope:** mobile.storage)
|
|
684
|
+
- `getInt(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: number | null }; status_code: 200 }>` — Retrieves an integer value from the native storage. (**OAuth Scope:** mobile.storage)
|
|
685
|
+
- `getString(key: string): Promise<{ error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 } | { result: { value: string | null }; status_code: 200 }>` — Retrieves a string value from the native storage. (**OAuth Scope:** mobile.storage)
|
|
686
|
+
- `remove(key: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Removes a single value from the native storage by key. (**OAuth Scope:** mobile.storage)
|
|
687
|
+
- `removeAll(): Promise<{ status_code: 204 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Removes all values from the native storage. (**OAuth Scope:** mobile.storage)
|
|
688
|
+
- `setBoolean(key: string, value: boolean): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores a boolean value in the native storage. (**OAuth Scope:** mobile.storage)
|
|
689
|
+
- `setDouble(key: string, value: number): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores a double (floating point) value in the native storage. (**OAuth Scope:** mobile.storage)
|
|
690
|
+
- `setInt(key: string, value: number): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores an integer value in the native storage. (**OAuth Scope:** mobile.storage)
|
|
691
|
+
- `setString(key: string, value: string): Promise<{ status_code: 204 } | { error: string; status_code: 400 } | { error: string; status_code: 500 } | { error: string; status_code: 501 } | { error: string; status_code: 424 }>` — Stores a string value in the native storage. (**OAuth Scope:** mobile.storage)
|
|
355
692
|
|
|
356
693
|
#### `SystemWebViewKitModule`
|
|
357
694
|
JSBridge module for opening URLs in the device's system browser.
|