Skip to main content
The @shopperlabs/shopper-types package provides comprehensive TypeScript type definitions for all Shopper models and entities. These types are useful when building storefronts, mobile apps, or any TypeScript application that interacts with the Shopper API.

Installation

npm install @shopperlabs/shopper-types

Usage

Import types directly from the package:
import type { Product, ProductVariant, Order } from '@shopperlabs/shopper-types'

// Use in your API calls
async function getProduct(id: number): Promise<Product> {
  const response = await fetch(`/api/products/${id}`)
  return response.json()
}

// Type your component props
interface ProductCardProps {
  product: Product
}

Available Types

The package exports types for all Shopper models:
TypeDescription
ProductProduct model with variants, categories, and media
ProductVariantProduct variant with pricing and attributes
ProductTagSimple label for cross-cutting product organization
OrderOrder with items, addresses, and shipping
OrderItemIndividual order line item
OrderShippingShipment with tracking and carrier
OrderShippingEventTracking event in a shipment timeline
OrderAddressShipping or billing address on an order
OrderRefundRefund request for an order
CustomerCustomer profile and addresses
CategoryHierarchical product category
BrandProduct brand
CollectionProduct collection (manual or automatic)
AttributeProduct attribute definition
AttributeValueAttribute value option
AddressCustomer address
ChannelSales channel
ZoneShipping/pricing zone
CarrierShipping carrier
CarrierOptionCarrier shipping option
CurrencyCurrency configuration
DiscountDiscount/coupon code
InventoryInventory location
PaymentMethodPayment method
ReviewProduct review
SupplierProduct supplier

Enums

The package also exports enums for type-safe status checks:
import {
  ProductType,
  OrderStatus,
  PaymentStatus,
  ShippingStatus,
  CollectionType,
  AddressType
} from '@shopperlabs/shopper-types'

if (product.type === ProductType.VARIANT) {
  // Handle variant product
}

if (order.status === OrderStatus.COMPLETED) {
  // Order is complete
}

if (order.payment_status === PaymentStatus.AUTHORIZED) {
  // Payment can be captured
}

Available Enums

EnumValues
ProductTypeSTANDARD, VARIANT, VIRTUAL, EXTERNAL
OrderStatusNEW, PROCESSING, COMPLETED, CANCELLED, ARCHIVED
PaymentStatusPENDING, AUTHORIZED, PAID, PARTIALLY_REFUNDED, REFUNDED, VOIDED
ShippingStatusUNFULFILLED, PARTIALLY_SHIPPED, SHIPPED, PARTIALLY_DELIVERED, DELIVERED, PARTIALLY_RETURNED, RETURNED
FulfillmentStatusPENDING, FORWARDED_TO_SUPPLIER, PROCESSING, SHIPPED, DELIVERED, CANCELLED
ShipmentStatusPENDING, PICKED_UP, IN_TRANSIT, AT_SORTING_CENTER, OUT_FOR_DELIVERY, DELIVERED, DELIVERY_FAILED, RETURNED
OrderRefundStatusPENDING, AWAITING, TREATMENT, PARTIAL_REFUND, REFUNDED, CANCELLED, REJECTED
CollectionTypeMANUAL, AUTO
CollectionConditionALL, ANY
CollectionRuleTypePRODUCT_TITLE, PRODUCT_BRAND, PRODUCT_CATEGORY, PRODUCT_PRICE, COMPARE_AT_PRICE, INVENTORY_STOCK, PRODUCT_CREATED_AT, PRODUCT_FEATURED, PRODUCT_RATING, PRODUCT_SALES_COUNT
CollectionOperatorEQUALS_TO, NOT_EQUAL_TO, LESS_THAN, GREATER_THAN, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS
AddressTypeBILLING, SHIPPING
DiscountTypePERCENTAGE, FIXED_AMOUNT
GenderTypeMALE, FEMALE
FieldTypeTEXT, NUMBER, RICH_TEXT, SELECT, CHECKBOX, COLOR_PICKER, DATE_PICKER
WeightKG, G, LBS
LengthM, CM, MM, FT, IN
VolumeL, ML, GAL, FLOZ

Common Interfaces

Entity

All models extend the base Entity interface:
interface Entity {
  id: number
  created_at?: DateEntity
  updated_at?: DateEntity
  deleted_at?: DateEntity | null
}

DateEntity

Dates are returned with both raw and human-readable formats:
interface DateEntity {
  date: string // e.g., "2026-02-11 14:30:00"
  human: string // e.g., "2 hours ago"
}

Price

Pricing information for products and variants:
interface Price {
  amount: number | null
  compare_amount: number | null
  cost_amount: number | null
  currency_id: number
  currency_code: string
  currency?: Currency
}

ShippingFields

Physical dimensions for shippable products:
interface ShippingFields {
  width_unit: Length
  width_value: number | null
  weight_unit: Weight
  weight_value: number | null
  height_unit: Length
  height_value: number | null
  depth_unit: Length
  depth_value: number | null
  volume_unit: Volume
  volume_value: number | null
}

Example: Storefront Product List

import type { Product, Category } from '@shopperlabs/shopper-types'
import { ProductType } from '@shopperlabs/shopper-types'

interface ProductListProps {
  products: Product[]
  category?: Category
}

function ProductList({ products, category }: ProductListProps) {
  return (
    <div>
      {category && <h1>{category.name}</h1>}

      {products.map((product) => (
        <div key={product.id}>
          <h2>{product.name}</h2>
          <p>{product.description}</p>

          {product.type === ProductType.VARIANT && (
            <span>{product.variants?.length} variants</span>
          )}

          {product.prices?.[0] && (
            <span>
              {product.prices[0].currency_code} {product.prices[0].amount}
            </span>
          )}
        </div>
      ))}
    </div>
  )
}

Example: Order Details

import type { Order, OrderItem } from '@shopperlabs/shopper-types'
import { OrderStatus, PaymentStatus, ShippingStatus } from '@shopperlabs/shopper-types'

function OrderDetails({ order }: { order: Order }) {
  const statusColors: Record<OrderStatus, string> = {
    [OrderStatus.NEW]: '#3b82f6',
    [OrderStatus.PROCESSING]: '#2563eb',
    [OrderStatus.COMPLETED]: '#059669',
    [OrderStatus.CANCELLED]: '#ef4444',
    [OrderStatus.ARCHIVED]: '#6b7280',
  }

  return (
    <div>
      <h1>Order #{order.number}</h1>

      <div>
        <span style={{ color: statusColors[order.status] }}>{order.status}</span>
        <span>{order.payment_status}</span>
        <span>{order.shipping_status}</span>
      </div>

      <h2>Items</h2>
      {order.items?.map((item: OrderItem) => (
        <div key={item.id}>
          <span>{item.name}</span>
          <span>x{item.quantity}</span>
          <span>{item.unit_price_amount}</span>
        </div>
      ))}

      {order.shippingAddress && (
        <div>
          <h2>Shipping Address</h2>
          <p>{order.shippingAddress.full_name}</p>
          <p>{order.shippingAddress.street_address}</p>
          <p>{order.shippingAddress.city}, {order.shippingAddress.state}</p>
          <p>{order.shippingAddress.postal_code}</p>
        </div>
      )}
    </div>
  )
}

Source Code

The types are open source and available on GitHub:

GitHub Repository

View the source code and contribute to the types package.