@hyve-sdk/js 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,6 +20,7 @@ pnpm add @hyve-sdk/js
20
20
  - **API Integration**: Authenticated API calls with JWT token support
21
21
  - **Inventory Management**: Built-in methods for user inventory operations
22
22
  - **Telemetry Tracking**: Session-based analytics and event tracking
23
+ - **Billing Integration**: Unified billing for web (Stripe) and native (In-App Purchases) platforms
23
24
  - **Ads Integration**: Google H5 Games Ads support (disabled by default)
24
25
  - **Native Bridge**: Type-safe communication with React Native WebView apps
25
26
  - **Logger**: Environment-aware logging system with configurable log levels
@@ -379,6 +380,219 @@ See [docs/ads.md](./docs/ads.md) for detailed documentation and examples.
379
380
  - JWT token must be available (via `hyve-access` URL parameter)
380
381
  - User must be authenticated
381
382
 
383
+ ## Billing Integration
384
+
385
+ The SDK includes unified billing support for both web (Stripe) and native (In-App Purchases) platforms. Billing automatically detects the platform and routes to the appropriate payment method.
386
+
387
+ ### Quick Start
388
+
389
+ ```typescript
390
+ import { HyveClient } from "@hyve-sdk/js";
391
+
392
+ // Enable billing in initial config
393
+ const client = new HyveClient({
394
+ isDev: true,
395
+ billing: {
396
+ stripePublishableKey: 'pk_test_...',
397
+ checkoutUrl: 'https://your-api.com',
398
+ }
399
+ });
400
+
401
+ // Authenticate user
402
+ await client.authenticateFromUrl(window.location.search);
403
+
404
+ // Initialize billing (uses client's userId and gameId automatically)
405
+ const initialized = await client.initializeBilling();
406
+
407
+ if (initialized && client.isBillingAvailable()) {
408
+ // Set up purchase callbacks
409
+ client.onPurchaseComplete((result) => {
410
+ console.log('Purchase successful!', result.transactionId);
411
+ // Refresh inventory
412
+ client.getInventory().then(inv => console.log('Updated inventory:', inv));
413
+ });
414
+
415
+ client.onPurchaseError((result) => {
416
+ console.error('Purchase failed:', result.error?.message);
417
+ });
418
+
419
+ // Get available products
420
+ const products = await client.getBillingProducts();
421
+ console.log('Available products:', products);
422
+
423
+ // Purchase a product
424
+ await client.purchaseProduct('price_1234', {
425
+ elementId: 'stripe-checkout-element' // For web platform
426
+ });
427
+ }
428
+ ```
429
+
430
+ ### Platform Support
431
+
432
+ The SDK automatically detects the platform and uses the appropriate billing method:
433
+
434
+ | Platform | Payment Method | Requirements |
435
+ |----------|---------------|--------------|
436
+ | Web | Stripe Embedded Checkout | Stripe publishable key |
437
+ | Native (iOS/Android) | In-App Purchases | Native app integration |
438
+
439
+ ### Prerequisites
440
+
441
+ For web platform, add a container element for Stripe checkout:
442
+
443
+ ```html
444
+ <div id="stripe-checkout-element"></div>
445
+ ```
446
+
447
+ Stripe.js will be loaded automatically by the SDK.
448
+
449
+ For native platform, ensure the mobile app implements the Native Bridge billing messages.
450
+
451
+ ### Configuration
452
+
453
+ ```typescript
454
+ interface BillingConfig {
455
+ stripePublishableKey?: string; // Stripe key for web (required for web)
456
+ checkoutUrl?: string; // API endpoint for checkout
457
+ gameId?: number; // Game identifier
458
+ userId?: string; // User identifier
459
+ }
460
+ ```
461
+
462
+ Note: When using billing through HyveClient, `userId` and `gameId` are automatically populated from the authenticated user.
463
+
464
+ ### Methods
465
+
466
+ ```typescript
467
+ // Configure billing after initialization
468
+ client.configureBilling({
469
+ stripePublishableKey: 'pk_live_...',
470
+ checkoutUrl: 'https://api.example.com'
471
+ });
472
+
473
+ // Initialize billing
474
+ await client.initializeBilling();
475
+
476
+ // Check platform and availability
477
+ const platform = client.getBillingPlatform(); // 'web' | 'native' | 'unknown'
478
+ const available = client.isBillingAvailable(); // Boolean
479
+
480
+ // Get products
481
+ const products = await client.getBillingProducts();
482
+
483
+ // Purchase a product
484
+ const result = await client.purchaseProduct(productId, {
485
+ elementId: 'stripe-checkout-element' // Optional, defaults to 'stripe-checkout-element'
486
+ });
487
+
488
+ // Set up callbacks
489
+ client.onPurchaseComplete((result) => {
490
+ console.log('Success!', result);
491
+ });
492
+
493
+ client.onPurchaseError((result) => {
494
+ console.error('Failed:', result.error);
495
+ });
496
+
497
+ // Optional: Listen to billing logs
498
+ client.onBillingLog((level, message, data) => {
499
+ console.log(`[${level}] ${message}`, data);
500
+ });
501
+
502
+ // Clean up checkout UI
503
+ client.unmountBillingCheckout();
504
+ ```
505
+
506
+ ### Product Interface
507
+
508
+ ```typescript
509
+ interface BillingProduct {
510
+ productId: string; // Product/price ID
511
+ title: string; // Product name
512
+ description: string; // Product description
513
+ price: number; // Price in dollars (e.g., 9.99)
514
+ localizedPrice: string; // Formatted price (e.g., "$9.99")
515
+ currency: string; // Currency code (e.g., "USD")
516
+ }
517
+ ```
518
+
519
+ ### Purchase Result
520
+
521
+ ```typescript
522
+ interface PurchaseResult {
523
+ success: boolean;
524
+ productId: string;
525
+ transactionId?: string;
526
+ transactionDate?: string;
527
+ error?: {
528
+ code: string;
529
+ message: string;
530
+ };
531
+ }
532
+ ```
533
+
534
+ ### Complete Example with Telemetry
535
+
536
+ ```typescript
537
+ const client = new HyveClient({
538
+ isDev: true,
539
+ billing: {
540
+ stripePublishableKey: process.env.VITE_STRIPE_KEY,
541
+ checkoutUrl: process.env.VITE_CHECKOUT_URL,
542
+ }
543
+ });
544
+
545
+ // Authenticate
546
+ await client.authenticateFromUrl();
547
+
548
+ // Initialize billing
549
+ await client.initializeBilling();
550
+
551
+ // Set up callbacks with telemetry
552
+ client.onPurchaseComplete((result) => {
553
+ // Send success telemetry
554
+ client.sendTelemetry(
555
+ 'shop',
556
+ 'purchase',
557
+ 'complete',
558
+ 'success',
559
+ null,
560
+ { productId: result.productId, transactionId: result.transactionId }
561
+ );
562
+
563
+ // Refresh inventory
564
+ client.getInventory();
565
+ });
566
+
567
+ client.onPurchaseError((result) => {
568
+ // Send error telemetry
569
+ client.sendTelemetry(
570
+ 'shop',
571
+ 'purchase',
572
+ 'error',
573
+ 'failed',
574
+ null,
575
+ {
576
+ productId: result.productId,
577
+ errorCode: result.error?.code,
578
+ errorMessage: result.error?.message
579
+ }
580
+ );
581
+ });
582
+
583
+ // Get and display products
584
+ const products = await client.getBillingProducts();
585
+ ```
586
+
587
+ See [docs/examples/billing-with-client-example.ts](./docs/examples/billing-with-client-example.ts) for detailed examples including React components and Phaser integration.
588
+
589
+ **Requirements:**
590
+ - JWT token must be available (via `hyve-access` URL parameter)
591
+ - User must be authenticated
592
+ - Game ID must be available (via `game-id` URL parameter or JWT)
593
+ - For web: Stripe publishable key required
594
+ - For native: Mobile app must implement Native Bridge billing integration
595
+
382
596
  ## Native Bridge (React Native WebView)
383
597
 
384
598
  Provides type-safe bidirectional communication between your web application and the React Native mobile app.
package/dist/index.d.mts CHANGED
@@ -171,138 +171,6 @@ declare class AdsService {
171
171
  isReady(): boolean;
172
172
  }
173
173
 
174
- /**
175
- * HyveClient configuration options
176
- */
177
- interface HyveClientConfig extends TelemetryConfig {
178
- /** Ads configuration (disabled by default) */
179
- ads?: AdConfig$1;
180
- }
181
- /**
182
- * HyveClient provides telemetry and authentication functionality for Hyve games
183
- */
184
- declare class HyveClient {
185
- private telemetryConfig;
186
- private apiBaseUrl;
187
- private sessionId;
188
- private userId;
189
- private jwtToken;
190
- private gameId;
191
- private adsService;
192
- /**
193
- * Creates a new HyveClient instance
194
- * @param config Optional configuration including telemetry and ads
195
- */
196
- constructor(config?: HyveClientConfig);
197
- /**
198
- * Authenticates a user from URL parameters
199
- * @param urlParams URL parameters or search string
200
- * @returns Promise resolving to boolean indicating success
201
- */
202
- authenticateFromUrl(urlParams?: URLSearchParams | string): Promise<boolean>;
203
- /**
204
- * Sends a user-level telemetry event using JWT authentication
205
- * Requires JWT token, authenticated user, and game ID from URL parameters
206
- * @param eventLocation Location where the event occurred
207
- * @param eventCategory Main category of the event
208
- * @param eventAction Primary action taken
209
- * @param eventSubCategory Optional sub-category
210
- * @param eventSubAction Optional sub-action
211
- * @param eventDetails Optional event details (object or JSON string)
212
- * @param customData Optional custom data (object or JSON string)
213
- * @param platformId Optional platform identifier
214
- * @returns Promise resolving to boolean indicating success
215
- */
216
- sendTelemetry(eventLocation: string, eventCategory: string, eventAction: string, eventSubCategory?: string | null, eventSubAction?: string | null, eventDetails?: Record<string, any> | string | null, customData?: Record<string, any> | null, platformId?: string | null): Promise<boolean>;
217
- /**
218
- * Makes an authenticated API call using the JWT token
219
- * @param endpoint API endpoint path (will be appended to base URL)
220
- * @param options Fetch options (method, body, etc.)
221
- * @returns Promise resolving to the API response
222
- */
223
- callApi<T = any>(endpoint: string, options?: RequestInit): Promise<T>;
224
- /**
225
- * Gets the user's inventory
226
- * @returns Promise resolving to the user's inventory
227
- */
228
- getInventory(): Promise<Inventory>;
229
- /**
230
- * Gets a specific inventory item by ID
231
- * @param itemId The inventory item ID
232
- * @returns Promise resolving to the inventory item details
233
- */
234
- getInventoryItem(itemId: string): Promise<InventoryItem>;
235
- /**
236
- * Updates the telemetry configuration
237
- * @param config New telemetry configuration
238
- */
239
- updateTelemetryConfig(config: TelemetryConfig): void;
240
- /**
241
- * Gets the current user ID
242
- * @returns Current user ID or null if not authenticated
243
- */
244
- getUserId(): string | null;
245
- /**
246
- * Gets the current session ID
247
- * @returns Current session ID
248
- */
249
- getSessionId(): string;
250
- /**
251
- * Gets the current JWT token
252
- * @returns Current JWT token or null if not available
253
- */
254
- getJwtToken(): string | null;
255
- /**
256
- * Gets the current game ID
257
- * @returns Current game ID or null if not available
258
- */
259
- getGameId(): string | null;
260
- /**
261
- * Gets the API base URL
262
- * @returns API base URL
263
- */
264
- getApiBaseUrl(): string;
265
- /**
266
- * Checks if user is authenticated
267
- * @returns Boolean indicating authentication status
268
- */
269
- isUserAuthenticated(): boolean;
270
- /**
271
- * Checks if JWT token is available
272
- * @returns Boolean indicating if JWT token is present
273
- */
274
- hasJwtToken(): boolean;
275
- /**
276
- * Logs out the current user
277
- */
278
- logout(): void;
279
- /**
280
- * Resets the client state
281
- */
282
- reset(): void;
283
- /**
284
- * Configure ads service
285
- * @param config Ads configuration
286
- */
287
- configureAds(config: AdConfig$1): void;
288
- /**
289
- * Show an ad
290
- * @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
291
- * @returns Promise resolving to ad result
292
- */
293
- showAd(type: AdType): Promise<AdResult>;
294
- /**
295
- * Check if ads are enabled
296
- * @returns Boolean indicating if ads are enabled
297
- */
298
- areAdsEnabled(): boolean;
299
- /**
300
- * Check if ads are ready to show
301
- * @returns Boolean indicating if ads are ready
302
- */
303
- areAdsReady(): boolean;
304
- }
305
-
306
174
  /**
307
175
  * Product information from the native app or server
308
176
  */
@@ -514,6 +382,197 @@ declare class BillingService {
514
382
  dispose(): void;
515
383
  }
516
384
 
385
+ /**
386
+ * HyveClient configuration options
387
+ */
388
+ interface HyveClientConfig extends TelemetryConfig {
389
+ /** Ads configuration (disabled by default) */
390
+ ads?: AdConfig$1;
391
+ /** Billing configuration (disabled by default) */
392
+ billing?: BillingConfig;
393
+ }
394
+ /**
395
+ * HyveClient provides telemetry and authentication functionality for Hyve games
396
+ */
397
+ declare class HyveClient {
398
+ private telemetryConfig;
399
+ private apiBaseUrl;
400
+ private sessionId;
401
+ private userId;
402
+ private jwtToken;
403
+ private gameId;
404
+ private adsService;
405
+ private billingService;
406
+ private billingConfig;
407
+ private billingCallbacks;
408
+ /**
409
+ * Creates a new HyveClient instance
410
+ * @param config Optional configuration including telemetry and ads
411
+ */
412
+ constructor(config?: HyveClientConfig);
413
+ /**
414
+ * Authenticates a user from URL parameters
415
+ * @param urlParams URL parameters or search string
416
+ * @returns Promise resolving to boolean indicating success
417
+ */
418
+ authenticateFromUrl(urlParams?: URLSearchParams | string): Promise<boolean>;
419
+ /**
420
+ * Sends a user-level telemetry event using JWT authentication
421
+ * Requires JWT token, authenticated user, and game ID from URL parameters
422
+ * @param eventLocation Location where the event occurred
423
+ * @param eventCategory Main category of the event
424
+ * @param eventAction Primary action taken
425
+ * @param eventSubCategory Optional sub-category
426
+ * @param eventSubAction Optional sub-action
427
+ * @param eventDetails Optional event details (object or JSON string)
428
+ * @param customData Optional custom data (object or JSON string)
429
+ * @param platformId Optional platform identifier
430
+ * @returns Promise resolving to boolean indicating success
431
+ */
432
+ sendTelemetry(eventLocation: string, eventCategory: string, eventAction: string, eventSubCategory?: string | null, eventSubAction?: string | null, eventDetails?: Record<string, any> | string | null, customData?: Record<string, any> | null, platformId?: string | null): Promise<boolean>;
433
+ /**
434
+ * Makes an authenticated API call using the JWT token
435
+ * @param endpoint API endpoint path (will be appended to base URL)
436
+ * @param options Fetch options (method, body, etc.)
437
+ * @returns Promise resolving to the API response
438
+ */
439
+ callApi<T = any>(endpoint: string, options?: RequestInit): Promise<T>;
440
+ /**
441
+ * Gets the user's inventory
442
+ * @returns Promise resolving to the user's inventory
443
+ */
444
+ getInventory(): Promise<Inventory>;
445
+ /**
446
+ * Gets a specific inventory item by ID
447
+ * @param itemId The inventory item ID
448
+ * @returns Promise resolving to the inventory item details
449
+ */
450
+ getInventoryItem(itemId: string): Promise<InventoryItem>;
451
+ /**
452
+ * Updates the telemetry configuration
453
+ * @param config New telemetry configuration
454
+ */
455
+ updateTelemetryConfig(config: TelemetryConfig): void;
456
+ /**
457
+ * Gets the current user ID
458
+ * @returns Current user ID or null if not authenticated
459
+ */
460
+ getUserId(): string | null;
461
+ /**
462
+ * Gets the current session ID
463
+ * @returns Current session ID
464
+ */
465
+ getSessionId(): string;
466
+ /**
467
+ * Gets the current JWT token
468
+ * @returns Current JWT token or null if not available
469
+ */
470
+ getJwtToken(): string | null;
471
+ /**
472
+ * Gets the current game ID
473
+ * @returns Current game ID or null if not available
474
+ */
475
+ getGameId(): string | null;
476
+ /**
477
+ * Gets the API base URL
478
+ * @returns API base URL
479
+ */
480
+ getApiBaseUrl(): string;
481
+ /**
482
+ * Checks if user is authenticated
483
+ * @returns Boolean indicating authentication status
484
+ */
485
+ isUserAuthenticated(): boolean;
486
+ /**
487
+ * Checks if JWT token is available
488
+ * @returns Boolean indicating if JWT token is present
489
+ */
490
+ hasJwtToken(): boolean;
491
+ /**
492
+ * Logs out the current user
493
+ */
494
+ logout(): void;
495
+ /**
496
+ * Resets the client state
497
+ */
498
+ reset(): void;
499
+ /**
500
+ * Configure ads service
501
+ * @param config Ads configuration
502
+ */
503
+ configureAds(config: AdConfig$1): void;
504
+ /**
505
+ * Show an ad
506
+ * @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
507
+ * @returns Promise resolving to ad result
508
+ */
509
+ showAd(type: AdType): Promise<AdResult>;
510
+ /**
511
+ * Check if ads are enabled
512
+ * @returns Boolean indicating if ads are enabled
513
+ */
514
+ areAdsEnabled(): boolean;
515
+ /**
516
+ * Check if ads are ready to show
517
+ * @returns Boolean indicating if ads are ready
518
+ */
519
+ areAdsReady(): boolean;
520
+ /**
521
+ * Configure billing service
522
+ * @param config Billing configuration
523
+ */
524
+ configureBilling(config: BillingConfig): void;
525
+ /**
526
+ * Initialize billing service
527
+ * Must be called before using billing features
528
+ * @returns Promise resolving to boolean indicating success
529
+ */
530
+ initializeBilling(): Promise<boolean>;
531
+ /**
532
+ * Get the billing platform
533
+ * @returns Current billing platform
534
+ */
535
+ getBillingPlatform(): BillingPlatform;
536
+ /**
537
+ * Check if billing is available
538
+ * @returns Boolean indicating if billing is available
539
+ */
540
+ isBillingAvailable(): boolean;
541
+ /**
542
+ * Get available billing products
543
+ * @returns Promise resolving to array of products
544
+ */
545
+ getBillingProducts(): Promise<BillingProduct[]>;
546
+ /**
547
+ * Purchase a product
548
+ * @param productId Product ID to purchase
549
+ * @param options Optional purchase options (e.g., elementId for web)
550
+ * @returns Promise resolving to purchase result
551
+ */
552
+ purchaseProduct(productId: string, options?: {
553
+ elementId?: string;
554
+ }): Promise<PurchaseResult>;
555
+ /**
556
+ * Set callback for successful purchases
557
+ * @param callback Function to call on purchase completion
558
+ */
559
+ onPurchaseComplete(callback: (result: PurchaseResult) => void): void;
560
+ /**
561
+ * Set callback for failed purchases
562
+ * @param callback Function to call on purchase error
563
+ */
564
+ onPurchaseError(callback: (result: PurchaseResult) => void): void;
565
+ /**
566
+ * Unmount Stripe checkout element
567
+ */
568
+ unmountBillingCheckout(): void;
569
+ /**
570
+ * Register a callback to receive billing logs
571
+ * @param callback Function to call with log messages
572
+ */
573
+ onBillingLog(callback: (level: "info" | "warn" | "error", message: string, data?: any) => void): void;
574
+ }
575
+
517
576
  /**
518
577
  * Logger utility for the Hyve SDK
519
578
  * Automatically enabled in development (NODE_ENV !== 'production')