Skip to content
Last updated

PERS SDK Introduction

The PERS SDK is a platform-agnostic TypeScript library that provides a clean, modern interface for integrating with the PERS (Phygital Experience Rewards System) platform. Built with a Manager-Service architecture, it offers consistent APIs for tourism loyalty applications across web, mobile, and server environments.

What is PERS?

PERS is a comprehensive tourism loyalty platform that bridges physical and digital experiences through:

  • Loyalty Programs - Token-based reward systems
  • Campaign Management - Marketing campaigns and challenges
  • Business Operations - Merchant and venue management
  • Payment Processing - Integrated payment solutions
  • Blockchain Integration - Web3 and digital token support
  • Analytics - Comprehensive reporting and insights

Installation

npm install @explorins/pers-sdk

Quick Start

Basic Setup

import { PersSDK } from '@explorins/pers-sdk';
import { BrowserFetchClientAdapter } from '@explorins/pers-sdk/platform-adapters';

const sdk = new PersSDK(new BrowserFetchClientAdapter(), {
  environment: 'production',
  apiProjectKey: 'your-project-key'
});

Authentication Flow

// Login with external JWT (Firebase, Auth0, etc.)
await sdk.auth.loginWithToken(firebaseJWT, 'user');

// Check authentication status
if (await sdk.auth.isAuthenticated()) {
  const user = await sdk.auth.getCurrentUser();
  console.log('Welcome,', user.name);
}

Core Operations

// Business operations
const businesses = await sdk.businesses.getActiveBusinesses();
const business = await sdk.businesses.getBusinessById('business-123');

// Campaign management
const campaigns = await sdk.campaigns.getActiveCampaigns();
const claim = await sdk.campaigns.claimCampaign({
  campaignId: 'campaign-123',
  businessId: 'business-456'  // Optional business context
});

// Token operations - get available tokens
const tokens = await sdk.tokens.getTokens();
const creditToken = await sdk.tokens.getActiveCreditToken();

// Transaction history
const transactions = await sdk.transactions.getUserTransactionHistory('user-456');

// File operations
const uploadUrl = await sdk.files.getSignedPutUrl('entity-123', 'profile-image', 'jpg');
const downloadUrl = await sdk.files.getSignedGetUrl('entity-123', 'profile-image');

Platform Integration

Angular

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { PersSDK } from '@explorins/pers-sdk';
import { AngularHttpClientAdapter } from '@explorins/pers-sdk/platform-adapters';

@Injectable({ providedIn: 'root' })
export class PersSDKService {
  private sdk: PersSDK;

  constructor(httpClient: HttpClient) {
    this.sdk = new PersSDK(new AngularHttpClientAdapter(httpClient), {
      environment: 'production',
      apiProjectKey: 'your-project-key'
    });
  }

  getSDK(): PersSDK {
    return this.sdk;
  }
}

React/Browser

import { PersSDK } from '@explorins/pers-sdk';
import { BrowserFetchClientAdapter } from '@explorins/pers-sdk/platform-adapters';

const sdk = new PersSDK(new BrowserFetchClientAdapter(), {
  environment: 'production',
  apiProjectKey: 'your-project-key'
});

// React Hook example
export function usePersSDK() {
  return sdk;
}

Node.js

import { PersSDK } from '@explorins/pers-sdk';
import { NodeHttpClientAdapter } from '@explorins/pers-sdk/platform-adapters';

const sdk = new PersSDK(new NodeHttpClientAdapter(), {
  environment: 'production',
  apiProjectKey: 'your-project-key'
});

Architecture Overview

The SDK follows a clean Manager-Service pattern:

Manager Layer (Primary Interface)

  • sdk.auth - Authentication and user sessions
  • sdk.users - User profile management
  • sdk.tokens - Token operations and balances
  • sdk.businesses - Business operations
  • sdk.campaigns - Marketing campaigns
  • sdk.redemptions - Reward redemptions
  • sdk.transactions - Transaction history
  • sdk.payments - Payment processing
  • sdk.files - File upload and management
  • sdk.analytics - Reporting and insights
  • sdk.tenants - Multi-tenant configuration
  • sdk.web3 - Blockchain operations

Service Layer (Advanced Access)

For advanced operations, you can access services directly:

const userService = sdk.users.getUserService();
const campaignService = sdk.campaigns.getCampaignService();
const fileService = sdk.files.getFileService();

Core Features

Authentication System

  • External JWT integration (Firebase, Auth0, custom providers)
  • Native token validation and refresh
  • Support for both user and admin authentication flows
  • Automatic token management and renewal

Business Management

  • Business registration and profile management
  • Business type categorization
  • Public business discovery
  • Admin tools for business operations

Campaign System

  • Create and manage marketing campaigns
  • User participation and claim tracking
  • Advanced campaign triggers and automation
  • Analytics and performance metrics

Token Economy

  • Multi-token support (credit, reward, utility tokens)
  • Balance management and transfers
  • Transaction history and analytics
  • Integration with external payment systems

File Management

  • Secure file upload and download
  • Signed URL generation for direct browser access
  • Media optimization and processing
  • Cloud storage integration

Reward Redemptions

  • Flexible redemption offer system
  • User redemption tracking
  • Multiple redemption types (discounts, products, experiences)
  • Inventory management

Configuration

interface PersConfig {
  environment?: 'development' | 'staging' | 'production';
  apiVersion?: 'v2';
  apiProjectKey: string;
  timeout?: number;
  retries?: number;
  authProvider?: PersAuthProvider;
  tokenRefreshMargin?: number;
  backgroundRefreshThreshold?: number;
}

Environment Configuration

  • development - Local development and testing
  • staging - Pre-production testing
  • production - Live environment

Authentication Options

You can provide a custom authentication provider or let the SDK create one automatically:

// Auto-created provider (recommended)
const sdk = new PersSDK(httpClient, {
  environment: 'production',
  apiProjectKey: 'your-key'
});

// Custom provider
const sdk = new PersSDK(httpClient, {
  environment: 'production',
  apiProjectKey: 'your-key',
  authProvider: customAuthProvider
});

Error Handling

The SDK provides comprehensive error handling with typed error responses:

import { PersApiError } from '@explorins/pers-sdk/core';

try {
  const user = await sdk.auth.getCurrentUser();
} catch (error) {
  if (error instanceof PersApiError) {
    console.error('API Error:', {
      message: error.message,
      status: error.statusCode,
      details: error.details
    });
  } else {
    console.error('Unexpected error:', error);
  }
}

Performance Features

  • Bundle Size: ~85 KB minified
  • Tree-shaking: Import only what you need
  • Zero External Auth Dependencies: Native browser APIs
  • Intelligent Token Refresh: Background refresh with race condition protection
  • Request Optimization: Automatic retry and timeout handling

TypeScript Support

The SDK is built with TypeScript and provides excellent type safety:

// Full type inference
const campaigns = await sdk.campaigns.getActiveCampaigns(); // CampaignDTO[]
const business = await sdk.businesses.getBusinessById('123'); // BusinessDTO

// Generic support for custom types
const customData = await sdk.api().get<CustomType>('/custom-endpoint');

Advanced Usage

Direct API Access

For operations not covered by managers:

const apiClient = sdk.api();
const customData = await apiClient.get('/custom-endpoint');
await apiClient.post('/custom-endpoint', data);

Custom HTTP Client

Implement your own HTTP client for specific requirements:

import { HttpClient, RequestOptions } from '@explorins/pers-sdk/core';

class CustomHttpClient implements HttpClient {
  async get<T>(url: string, options?: RequestOptions): Promise<T> {
    // Your implementation
  }
  // ... other methods
}

const sdk = new PersSDK(new CustomHttpClient(), config);

Support and Resources

License

MIT License - See package for full license details.