window.MageSDK. Since it isn’t an npm package, TypeScript won’t know about it by default. You can add full type support by creating a declaration file in your project.
Setup
Create a file calledmage-sdk.d.ts anywhere in your project (e.g. the root, or a types/ folder):
mage-sdk.d.ts
interface MageSDKResponse<T = unknown> {
success: boolean;
error?: string;
data?: T;
}
// 'store_credit' shops denominate every loyalty NUMBER (points, pointsCost,
// balances) in ISO minor units. See the Loyalty modes guide.
type MageLoyaltyMode = 'points' | 'store_credit';
// Computed by the SDK (not sent by the server) in store-credit mode.
interface MageStoreCreditBalance {
balanceMinor: number;
balance: string; // major-unit decimal, e.g. "3.00"
balanceFormatted: string; // display string, e.g. "$3.00"
currency: string;
}
interface MageTierReward {
id: string;
name: string;
discountType: string | null;
discountAmount: number | null;
pointsCost: number;
isActive: boolean;
isEntryReward?: boolean;
expiryDays?: number | null;
}
interface MageVipTier {
id: string;
name: string;
description: string | null;
threshold: number;
thresholdPoints?: number | null;
thresholdSpend?: number | null;
thresholdOrders?: number | null;
pointsMultiplier: number;
badgeImageUrl: string | null;
badgeColor: string | null;
rewards: MageTierReward[];
}
interface MageCustomerEarningEntry {
id: string;
earningRuleId: string;
status: string;
points: number;
refundedPoints: number;
createdAt: string;
action: string | null;
name: string;
pointsExpiryAt: string | null;
earningRule: { id: string; name: string } | null;
}
interface MageReferralEarning {
id: string;
type: string;
status: string;
friendEmail: string;
createdAt: string;
friendDiscountCreatedAt?: string | null;
referrerDiscountCreatedAt?: string | null;
}
interface MageCustomerDetails {
id: string;
shopifyCustomerId: string;
email: string;
firstName: string;
lastName: string;
points: number;
lifetimePoints: number;
redeemedPoints: number;
isExcluded: boolean;
dateOfBirth: string | null;
referralCode: string | null;
referralUrl: string | null;
tier: MageVipTier | null;
tierProgressValue: number;
tierProgressValueExtra?: number | null;
customerEarningRule: MageCustomerEarningEntry[];
earningHistory: MageCustomerEarningEntry[]; // back-compat alias
referralEarnings: MageReferralEarning[];
storeCredit?: MageStoreCreditBalance | null;
createdAt: string;
updatedAt: string;
}
interface MageFlexibleConfig {
conversionRate: number;
perPoints: number;
minPoints: number;
maxPoints: number;
}
interface MageReward {
id: string;
name: string;
description: string;
descriptionRequirements?: { type: string; text: string }[];
pointsCost: number;
category: string;
discountType: string | null;
discountAmount?: number | null;
iconUrl?: string | null;
tier: MageVipTier | null;
minimumSpend?: string;
redemptionMode?: 'fixed' | 'flexible';
purchaseType?: 'ONE_TIME' | 'SUBSCRIPTION' | 'BOTH';
recurringCycleLimit?: number | null;
flexibleConfig?: MageFlexibleConfig | null;
productMetadata?: {
productId?: string;
productTitle?: string;
productImage?: string | null;
productImageAlt?: string | null;
productHandle?: string | null;
items?: Array<{
id: string;
title: string;
image: string | null;
handle?: string;
type: 'product' | 'collection';
}>;
catalogType?: 'product' | 'collection';
} | null;
}
interface MageCustomerReward {
id: string;
rewardName: string;
rewardDescription?: string;
points: number;
discountCode: string;
discountType?: string | null;
discountValue?: string | null;
status: string;
createdAt: string;
expiresAt: string | null;
discountCodeRedeemedAt?: string | null;
productImage?: string | null;
validVariants?: unknown[];
isCustomerReward?: boolean;
isReferral?: boolean;
isReferrer?: boolean;
}
interface MageEarningRule {
id: string;
name: string;
description: string | null;
action: string;
category: string;
isActive: boolean;
pointsToGive: number;
customerFacingLabel: string | null;
callToActionUrl: string | null;
fullCallToActionUrl?: string | null;
points?: number; // final award after boosts (display this)
basePoints?: number;
tierBoost?: number | null;
campaignBoost?: number | null;
photoReviewPoints?: number | null;
videoReviewPoints?: number | null;
receiptConfig?: Record<string, unknown> | null;
reviewConfig?: Record<string, unknown> | null;
photoChallengeConfig?: Record<string, unknown> | null;
customerEarningRule?: {
id: string;
earningRuleId: string;
status: string;
points: number;
createdAt: string;
} | null;
}
type MageActivityEntryType = 'earning' | 'redemption' | 'cashback';
interface MageActivityEntry {
id: string;
type: MageActivityEntryType;
name: string;
points: number;
refundedPoints: number;
status: string;
createdAt: string;
pointsExpiryAt: string | null;
amount?: number; // cashback rows only
refundedAmount?: number; // cashback rows only
currencySymbol?: string; // cashback rows only
}
interface MageCustomerProfile {
firstName: string;
lastName: string;
email?: string;
acceptsMarketing?: boolean;
}
interface MageReferralStats {
summary: {
totalReferrals: number;
pending: number;
friendConverted: number;
completed: number;
expired: number;
availableRewards: number;
};
referrals: Array<{
id: string;
friendEmail: string;
status: string;
createdAt: string;
friendOrderDate?: string | null;
referrerDiscountCode?: string | null;
referrerDiscountUsed?: boolean;
referrerDiscountExpiresAt?: string | null;
}>;
}
interface MageReferralLink {
enabled: boolean;
referralCode?: string;
referralUrl?: string;
stats?: {
totalReferred: number;
completedReferrals: number;
pendingReferrals: number;
};
socialSharing?: {
twitter: boolean;
twitterMessage: string | null;
facebook: boolean;
email: boolean;
whatsapp: boolean;
whatsappMessage: string | null;
sms?: boolean;
smsMessage?: string | null;
};
message?: string;
}
interface MageLoyaltySDK {
// Customers
getCustomerDetails(): Promise<MageSDKResponse<{ customer: MageCustomerDetails; loyaltyMode: MageLoyaltyMode; currency: string }>>;
getCustomerVipTier(): Promise<MageSDKResponse<{ tier: MageVipTier | null; tierProgressValue: number }>>;
updateCustomerDob(dob: string): Promise<boolean>;
getProfile(): Promise<MageSDKResponse<{ profile: MageCustomerProfile }>>;
updateProfile(input: { firstName: string; lastName: string; acceptsMarketing?: boolean }): Promise<MageSDKResponse<{ profile: MageCustomerProfile }>>;
getCustomerActivity(options?: { limit?: number; offset?: number }): Promise<MageSDKResponse<{
points: number;
pointsNextExpiryAt: string | null;
hasCashback: boolean;
activity: MageActivityEntry[];
pagination: { hasMore: boolean; totalCount: number };
content: { greeting: string; description: string };
loyaltyMode: MageLoyaltyMode;
currency: string;
}>>;
// Rewards
getShopRewards(): Promise<MageSDKResponse<{ regularRewards: MageReward[]; tieredRewards: MageReward[]; currencySymbol: string; subscriptionsProvider: string | null; loyaltyMode: MageLoyaltyMode; currency: string }>>;
getCustomerRewards(): Promise<MageSDKResponse<{ customerRewards: MageCustomerReward[] }>>;
redeemReward(rewardId: string): Promise<MageSDKResponse<{ discountCode: string; reward: { name: string; discountType: string | null }; customerReward: MageCustomerReward }>>;
redeemFlexible(rewardId: string, pointsToRedeem: number): Promise<MageSDKResponse<{ customerReward: { id: string; discountCode: string }; discountAmount: number; pointsRedeemed: number; updatedPoints: number }>>;
// Cart
getCartEarningValue(): Promise<MageSDKResponse<{ points: number; formatted: string; loyaltyMode: MageLoyaltyMode }>>;
// VIP Tiers
getShopVipTiers(): Promise<MageSDKResponse<{ tiers: MageVipTier[]; entryMethod: string; entryMethodExtra: string | null; entryLogic: 'AND' | 'OR'; currencySymbol: string; pointsMultiplierMode: string | null; loyaltyMode: MageLoyaltyMode; currency: string | null }>>;
// Earning Rules
getEarningRules(): Promise<MageSDKResponse<{ earningRules: MageEarningRule[]; loyaltyMode: MageLoyaltyMode; currency: string; tierInfo: { multiplier: number; name: string; mode: string } | null; campaignInfo: { name: string; id: string } | null }>>;
// Referrals
getCustomerReferralStats(): Promise<MageSDKResponse<MageReferralStats>>;
getReferralLink(): Promise<MageSDKResponse<MageReferralLink>>;
// Sidebar
openSidebar(): void;
closeSidebar(): void;
// Loyalty value formatting (points vs store credit)
formatLoyaltyValue(value: number, mode?: string | null, currency?: string | null): string;
formatSignedLoyaltyValue(value: number, mode?: string | null, currency?: string | null): string;
loyaltyUnitLabel(mode?: string | null, count?: number): string;
resolveLoyaltyMode(mode?: string | null): MageLoyaltyMode;
isStoreCredit(mode?: string | null): boolean;
minorToMajor(amountMinor: number, currency?: string | null): number;
}
interface Window {
MageSDK: MageLoyaltySDK;
}
tsconfig.json (it will be automatically if it’s inside your project root or include paths).
Usage
Once the declaration file is in place, you get full autocomplete and type checking:// TypeScript now knows about window.MageSDK
const resp = await window.MageSDK.getCustomerDetails();
if (resp.success && resp.data) {
const { customer, loyaltyMode, currency } = resp.data;
// Format the balance correctly whether the shop runs points or store credit
const label = window.MageSDK.formatLoyaltyValue(customer.points, loyaltyMode, currency);
console.log(label); // "450" (points) or "$4.50" (store credit)
console.log(customer.tier?.name); // string | undefined
}