Skip to main content

Examples

Complete working examples demonstrating various SDK features.

Live Examples

The SDK includes several HTML examples you can run locally:
ExampleDescriptionFile
QR LoginCustomer authentication via QRexamples/qr-login-example.html
QR Card ScanPOS customer identificationexamples/qr-card-scan-example.html
Full POS SystemComplete POS simulationexamples/pos-full-example.html

Running Examples

# Clone the repository
git clone https://github.com/Loyalty-lt/sdk-javascript.git
cd sdk-javascript

# Install dependencies & build
yarn install
yarn build

# Open examples in browser
open examples/qr-login-example.html

POS System Example

A complete Point of Sale implementation with customer identification, cart management, and points processing.

Features

  • Split-screen layout (Customer Display + POS Interface)
  • QR code customer identification
  • Real-time Ably updates
  • Product catalog
  • Cart with points earning preview
  • Points redemption
  • Manual card lookup
  • Send app download link

Key Code

import { LoyaltySDK } from '@loyaltylt/sdk';

class POSSystem {
  private sdk: LoyaltySDK;
  private currentCustomer: Customer | null = null;
  private cart: CartItem[] = [];
  
  constructor(apiKey: string, apiSecret: string) {
    this.sdk = new LoyaltySDK({
      apiKey,
      apiSecret,
      environment: 'production'
    });
  }
  
  // Start customer identification
  async startIdentification() {
    const session = await this.sdk.generateQrCardSession('POS');
    this.displayQR(session.qr_code);
    
    // Get Ably options with automatic token renewal
    const ablyOptions = await this.sdk.createAblyClientOptions(session.session_id);
    const tokenResponse = await this.sdk.getAblyToken(session.session_id);
    
    // Connect to Ably (token auto-renews)
    const ably = new Ably.Realtime(ablyOptions);
    const channel = ably.channels.get(tokenResponse.channel);
    
    channel.subscribe('card_identified', (message) => {
      this.handleCustomerIdentified(message.data.card_data);
    });
  }
  
  // Process checkout
  async checkout() {
    const total = this.calculateTotal();
    const pointsToEarn = Math.floor(total * 10);
    
    await this.sdk.createTransaction({
      card_id: this.currentCustomer.cardId,
      amount: total,
      points: pointsToEarn,
      type: 'earn',
      description: 'Purchase',
      reference: `POS-${Date.now()}`
    });
    
    this.showSuccess(`+${pointsToEarn} points earned!`);
    this.clearCart();
    this.clearCustomer();
  }
}

Points Calculation

Use the SDK’s built-in calculation functions for accurate points math:
import { 
  calculateAmountFromPoints,
  calculatePointsFromAmount,
  calculateFinalAmount 
} from '@loyaltylt/sdk';

// Points rules from card_identified event
const pointsRules = cardData.redemption;

// Calculate discount value
const discount = calculateAmountFromPoints(500, pointsRules);
// 500 points = 5.00 EUR

// Calculate points to earn
const pointsToEarn = calculatePointsFromAmount(cartTotal, pointsRules);
// 25.00 EUR = 250 points

// Calculate final amount after discount
const finalAmount = calculateFinalAmount(cartTotal, pointsToRedeem, pointsRules);
// 50.00 EUR - 5.00 EUR = 45.00 EUR
Always use the pointsRules from the backend instead of hardcoding values. Rules can vary per partner and may change.

React Integration

Next.js App Router

// app/loyalty/page.tsx
'use client';

import { useState, useEffect } from 'react';
import { QRLogin, QRCardDisplay } from '@loyaltylt/sdk/react';
import '@loyaltylt/sdk/styles';

export default function LoyaltyPage() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [userToken, setUserToken] = useState<string | null>(null);
  
  useEffect(() => {
    const token = localStorage.getItem('loyalty_token');
    if (token) {
      setUserToken(token);
      setIsLoggedIn(true);
    }
  }, []);
  
  if (!isLoggedIn) {
    return (
      <div className="flex min-h-screen items-center justify-center">
        <QRLogin
          apiKey={process.env.NEXT_PUBLIC_LOYALTY_API_KEY!}
          apiSecret={process.env.NEXT_PUBLIC_LOYALTY_API_SECRET!}
          onAuthenticated={(user, token) => {
            localStorage.setItem('loyalty_token', token);
            setUserToken(token);
            setIsLoggedIn(true);
          }}
        />
      </div>
    );
  }
  
  return (
    <div className="container mx-auto p-8">
      <h1 className="text-2xl font-bold mb-6">Your Loyalty Card</h1>
      <QRCardDisplay
        apiKey={process.env.NEXT_PUBLIC_LOYALTY_API_KEY!}
        apiSecret={process.env.NEXT_PUBLIC_LOYALTY_API_SECRET!}
        userToken={userToken!}
        showPoints
        showUserInfo
      />
    </div>
  );
}

Environment Variables

# .env.local
NEXT_PUBLIC_LOYALTY_API_KEY=lty_your_api_key
NEXT_PUBLIC_LOYALTY_API_SECRET=your_api_secret

Node.js Backend

Express.js Integration

// server.ts
import express from 'express';
import { LoyaltySDK } from '@loyaltylt/sdk';

const app = express();
app.use(express.json());

const sdk = new LoyaltySDK({
  apiKey: process.env.LOYALTY_API_KEY!,
  apiSecret: process.env.LOYALTY_API_SECRET!,
  environment: 'production'
});

// Award points after purchase
app.post('/api/orders/complete', async (req, res) => {
  const { orderId, cardNumber, amount } = req.body;
  
  try {
    // Find customer's card
    const cards = await sdk.getLoyaltyCards({ card_number: cardNumber });
    
    if (!cards.data.length) {
      return res.status(404).json({ error: 'Card not found' });
    }
    
    const card = cards.data[0];
    const pointsToAward = Math.floor(amount * 10);
    
    // Award points
    const transaction = await sdk.createTransaction({
      card_id: card.id,
      amount,
      points: pointsToAward,
      type: 'earn',
      description: `Order #${orderId}`,
      reference: orderId
    });
    
    res.json({
      success: true,
      points_awarded: pointsToAward,
      new_balance: card.points_balance + pointsToAward
    });
    
  } catch (error) {
    console.error('Error awarding points:', error);
    res.status(500).json({ error: 'Failed to award points' });
  }
});

// Get customer info by card number
app.get('/api/customers/lookup', async (req, res) => {
  const { card_number } = req.query;
  
  try {
    const cards = await sdk.getLoyaltyCards({ card_number: String(card_number) });
    
    if (!cards.data.length) {
      return res.status(404).json({ error: 'Card not found' });
    }
    
    const card = cards.data[0];
    res.json({
      name: card.user?.name,
      card_number: card.card_number,
      points: card.points_balance,
      status: card.status
    });
    
  } catch (error) {
    res.status(500).json({ error: 'Lookup failed' });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Webhooks Integration

// Handle loyalty webhooks
app.post('/api/webhooks/loyalty', async (req, res) => {
  const { event, data } = req.body;
  
  switch (event) {
    case 'points.awarded':
      console.log(`Customer ${data.customer_id} earned ${data.points} points`);
      // Update your database, send notification, etc.
      break;
      
    case 'points.redeemed':
      console.log(`Customer ${data.customer_id} redeemed ${data.points} points`);
      break;
      
    case 'offer.claimed':
      console.log(`Customer claimed offer: ${data.offer_id}`);
      break;
  }
  
  res.json({ received: true });
});

GitHub Repository

All examples are available in the SDK repository:

GitHub Repository

View complete source code and examples

Next Steps