Loyalty.lt
SDKsJavaScript

QR Card Scan

Identify a customer at the till by having them scan a QR code

QR Card Scan

QR card scan is the POS counterpart to QR login. The till shows a QR code, the customer scans it in the Loyalty.lt app, and the till receives their loyalty card — number, points balance and redemption rules — without asking for a phone number.

It identifies a card; it does not sign anyone in. Use QR Login when you need a customer token.

Flow

// 1. Open a session and render session.qr_code
const session = await sdk.generateQrCardSession('Till 3', shopId);

// 2. Wait for the customer to scan
const subscription = await sdk.subscribeToQrCardScan(session.session_id, ({ data }) => {
  const card = data.card_data;

  console.log('Card:', card.card_number);
  console.log('Points:', card.points);
  console.log('Customer:', card.user.name);

  if (card.redemption?.enabled) {
    console.log('Max redeemable:', card.redemption.max_points);
  }
});

// 3. When the sale is done
subscription.unsubscribe();

Sessions expire after 5 minutes. session.expires_at carries the deadline.

Fallback: polling

Only if your environment cannot hold a WebSocket open.

const session = await sdk.generateQrCardSession('Till 3', shopId);

const timer = setInterval(async () => {
  const status = await sdk.pollQrCardStatus(session.session_id);

  if (status.status === 'authenticated') {
    clearInterval(timer);
    // fetch the card and continue
  }
  if (status.status === 'expired') {
    clearInterval(timer);
  }
}, 1000);

What comes back

{
  session_id: string;
  status: 'authenticated';
  card_data: {
    loyalty_card_id: number;
    card_number: string;
    points: number;
    user: { id: number; name: string; email: string; phone?: string };
    redemption?: { enabled: boolean; max_points: number; /* ... */ };
  };
}

After identifying the customer

Use card_data to finish the sale:

// Their coupons for this shop
const coupons = await sdk.getCardCoupons(shopId, card.loyalty_card_id);

// Their active stamp cards
const games = await sdk.getCardGames(card.loyalty_card_id, shopId);

// Register the purchase and award the points
await sdk.createTransaction({
  user_id: card.user.id,
  order_id: `POS-${Date.now()}`,
  order_total: 25.50,
  currency: 'EUR',
  shop_id: shopId,
});

Next

<QRCardDisplay /> renders the customer-side card

Every channel, event and payload — including the live basket the SDK does not wrap

On this page