Skip to main content

Documentation Index

Fetch the complete documentation index at: https://86d.app/docs/llms.txt

Use this file to discover all available pages before exploring further.

The loyalty module gives your customers a points-based rewards program with four built-in tiers (bronze, silver, gold, platinum), configurable earning rules, and automatic point accrual whenever an order is placed. Accounts are provisioned automatically on a customer’s first interaction; no manual setup is required. Source: modules/loyalty · npm: @86d-app/loyalty

Installation

npm install @86d-app/loyalty
Add the module to your store configuration:
import loyalty from "@86d-app/loyalty";
import { createModuleClient } from "@86d-app/core";

const client = createModuleClient([
  loyalty({
    pointsPerDollar: "1",
    minRedemption: "100",
    redemptionRate: "100", // 100 points = $1
  }),
]);
The loyalty module requires the customers module to be enabled.

Configuration

pointsPerDollar
string
default:"1"
Number of points a customer earns per dollar spent. Applied to the order amount at the time the order.placed event fires.
minRedemption
string
Minimum point balance required before a customer can redeem. Customers with fewer points than this threshold cannot use the /loyalty/redeem endpoint.
redemptionRate
string
Points-to-currency conversion rate. A value of "100" means 100 points = $1.
All configuration values are strings for module config system compatibility, even though they represent numbers.

Store endpoints

MethodPathDescription
GET/loyalty/balanceGet the authenticated customer’s current point balance
GET/loyalty/transactionsList the customer’s point transaction history
GET/loyalty/tiersList all loyalty tiers
GET/loyalty/calculateCalculate how many points an order amount would earn
POST/loyalty/redeemRedeem points against an order
GET/loyalty/store-searchSearch loyalty data (store search integration)

Redeem points (POST /loyalty/redeem)

{
  "points": 500,
  "orderId": "ord_abc123"
}
Returns the resulting LoyaltyTransaction on success, or 400 if the customer has insufficient points or the amount is below minRedemption.

Calculate points (GET /loyalty/calculate)

Pass amount as a query parameter (in dollars):
GET /loyalty/calculate?amount=49.99
Returns { "points": 49 } based on active earning rules.

Admin endpoints

MethodPathDescription
GET/admin/loyalty/accountsList loyalty accounts (filter by tier, status)
GET/admin/loyalty/accounts/:customerIdGet a single customer’s loyalty account
POST/admin/loyalty/accounts/:customerId/adjustManually add or deduct points
POST/admin/loyalty/accounts/:customerId/suspendSuspend a loyalty account
POST/admin/loyalty/accounts/:customerId/reactivateReactivate a suspended account
GET/admin/loyalty/summaryGet program-wide statistics
GET/admin/loyalty/rulesList earning rules
POST/admin/loyalty/rules/createCreate an earning rule
PUT/admin/loyalty/rules/:id/updateUpdate an earning rule
DELETE/admin/loyalty/rules/:id/deleteDelete an earning rule
GET/admin/loyalty/tiersList tiers
POST/admin/loyalty/tiers/createCreate a tier
PUT/admin/loyalty/tiers/:id/updateUpdate a tier
DELETE/admin/loyalty/tiers/:id/deleteDelete a tier

Store components

Use these components in your MDX template files.

PointsBalance

Displays the customer’s current point balance with a tier badge and lifetime earn/redeem stats.
customerId
string
The customer’s ID. If omitted, the component shows a sign-in prompt.
<PointsBalance customerId={session.customerId} />
States: signed out (sign-in prompt) → loading (skeleton) → loaded (balance, tier badge, lifetime stats).

TierProgress

Shows the customer’s current tier and a visual progress bar toward the next tier. Displays a multiplier badge when the current tier has a points multiplier greater than 1×.
customerId
string
The customer’s ID. If omitted, the component shows a sign-in prompt.
<TierProgress customerId={session.customerId} />
States: signed out → loading (skeleton) → loaded (progress bar, percentage to next tier, tier step indicators with checkmarks).

PointsHistory

A filterable table of the customer’s point transactions (earn, redeem, adjust, expire).
customerId
string
The customer’s ID. If omitted, the component shows a sign-in prompt.
limit
number
default:"10"
Maximum number of transactions to display.
<PointsHistory customerId={session.customerId} limit={20} />
States: signed out → loading (skeleton rows) → loaded (filter bar + transaction table) → empty (“No transactions found”).

LoyaltyPage

A full-page loyalty dashboard that composes PointsBalance, TierProgress, and PointsHistory into a single view with a two-column layout.
customerId
string
The customer’s ID. If omitted, the component shows a sign-in prompt.
<LoyaltyPage customerId={session.customerId} />

Types

type LoyaltyTierSlug = "bronze" | "silver" | "gold" | "platinum";
type TransactionType = "earn" | "redeem" | "adjust" | "expire";
type AccountStatus = "active" | "suspended" | "closed";

interface LoyaltyAccount {
  id: string;
  customerId: string;
  balance: number;
  lifetimeEarned: number;
  lifetimeRedeemed: number;
  tier: LoyaltyTierSlug;
  status: AccountStatus;
  createdAt: Date;
  updatedAt: Date;
}

interface LoyaltyTransaction {
  id: string;
  accountId: string;
  type: TransactionType;
  points: number;
  description: string;
  orderId?: string;
  metadata?: Record<string, unknown>;
  createdAt: Date;
}

interface LoyaltyRule {
  id: string;
  name: string;
  type: "per_dollar" | "fixed_bonus" | "multiplier" | "signup";
  points: number;
  minOrderAmount?: number;
  active: boolean;
  createdAt: Date;
}

interface LoyaltyTier {
  id: string;
  name: string;
  slug: string;
  minPoints: number;
  multiplier: number;
  perks?: Record<string, unknown>;
  sortOrder: number;
}

interface LoyaltySummary {
  totalAccounts: number;
  totalPointsOutstanding: number;
  totalLifetimeEarned: number;
  tierBreakdown: Array<{ tier: LoyaltyTierSlug; count: number }>;
}

Rule types

TypeDescription
per_dollarAward a fixed number of points per dollar spent
fixed_bonusAward a flat point bonus when the order meets a minimum amount
multiplierMultiply the base points earned by a factor
signupOne-time bonus awarded on a customer’s first interaction