Types
The @commercejs/types package defines the shared vocabulary for all CommerceJS packages. It contains only TypeScript interfaces and type definitions — no runtime code.
Installation
pnpm add @commercejs/types
Usage
Import types directly from the package:
import type { Product, Cart, Order, Customer } from '@commercejs/types'
import type { PaymentProvider, PaymentSession } from '@commercejs/types'
import type { CommerceAdapter, CatalogAdapter } from '@commercejs/types'
import type { Profile, SavedAddress, SavedPaymentMethod } from '@commercejs/types'
import type { DeliveryProvider, DeliveryEstimate } from '@commercejs/types'
import type { StorageProvider, StorageUploadResult } from '@commercejs/types'
Domain Types
Product
interface Product {
id: string
name: LocalizedString
slug: string
description: LocalizedString
type: ProductType
price: DiscountablePrice
sku?: string
barcode?: string
quantity?: number
variants: ProductVariant[]
options: ProductOption[]
images: Image[]
attributes: Attribute[]
categories: Category[]
brand?: Brand
metadata?: Record<string, unknown>
}
Cart
interface Cart {
id: string
items: CartItem[]
totals: CartTotals
currency: string
metadata?: Record<string, unknown>
}
interface CartItem {
id: string
productId: string
variantId?: string
name: LocalizedString
quantity: number
price: Price
image?: Image
}
Order
interface Order {
id: string
status: OrderStatus
fulfillmentStatus: FulfillmentStatus
items: OrderItem[]
currency: string
subtotal: number
total: number
shippingTotal: number
taxTotal: number
discountTotal: number
customer: Customer
shippingAddress: Address
billingAddress: Address
paymentMethod?: PaymentMethod
shippingMethod?: ShippingMethod
createdAt: string
updatedAt: string
}
Order Input
For programmatically creating orders:
interface CreateOrderInput {
items: OrderItemInput[]
customer: Customer
shippingAddress: Address
billingAddress?: Address
shippingMethod?: ShippingMethod
paymentMethod?: PaymentMethod
currency: string
metadata?: Record<string, unknown>
}
Order Status & History
interface OrderStatusInfo {
status: OrderStatus
label: string
description?: string
}
interface OrderHistoryEntry {
status: OrderStatus
timestamp: string
note?: string
}
interface UpdateOrderStatusInput {
status: OrderStatus
note?: string
}
Customer
interface Customer {
id: string
email: string
firstName: string
lastName: string
phone?: string
addresses: Address[]
metadata?: Record<string, unknown>
}
interface Address {
id: string
street: string | null
street2: string | null
city: string
state: string | null
country: string
postalCode: string | null
district: string | null
nationalAddress: string | null
isDefault: boolean
}
Profile
Cross-merchant buyer identity for Commerce.js Cloud:
interface Profile {
id: string
email: string | null
phone: string | null
firstName: string | null
lastName: string | null
preferences: Record<string, any> | null
addresses: SavedAddress[]
paymentMethods: SavedPaymentMethod[]
createdAt: string
updatedAt: string
}
interface SavedAddress {
id: string
label: string | null
firstName: string
lastName: string
phone: string | null
street: string
street2: string | null
city: string
state: string | null
country: string
postalCode: string | null
district: string | null
nationalAddress: string | null
additionalNumber: string | null
lastUsedAt: string | null
createdAt: string
}
interface SavedPaymentMethod {
id: string
provider: string
type: string
last4: string
brand: string | null
expiryMonth: number | null
expiryYear: number | null
billingAddress: Record<string, any> | null
lastUsedAt: string | null
createdAt: string
}
interface ProfileMerchantLink {
profileId: string
merchantId: string
adapterCustomerId: string | null
}
Shipping Types
ShippingMethod
type FulfillmentType = 'shipping' | 'local_delivery' | 'pickup'
interface ShippingMethod {
id: string
name: LocalizedString
provider: ShippingProvider | string
fulfillmentType: FulfillmentType
estimatedDays: { min: number; max: number }
estimatedMinutes?: number // For local delivery (e.g. Armada, Parcel)
price: Price
cashOnDelivery: boolean
}
The fulfillmentType field enables the UI to render context-appropriate labels:
| Type | UI Label Example |
|---|---|
'shipping' | 3–5 business days |
'local_delivery' | ~30 min delivery |
'pickup' | Ready for pickup |
Payment Types
PaymentProvider
The pluggable interface that all payment gateways implement:
interface PaymentProvider {
createSession(input: CreatePaymentSessionInput): Promise<PaymentSession>
confirmSession(sessionId: string): Promise<PaymentSession>
refund(input: RefundInput): Promise<PaymentSession>
verifyWebhook(event: PaymentWebhookEvent): Promise<boolean>
}
PaymentSession
Tracks the lifecycle of a single payment:
interface PaymentSession {
id: string
providerId: string
status: PaymentSessionStatus
amount: number
currency: string
redirectUrl: string | null
providerData?: Record<string, unknown>
createdAt: string
}
type PaymentSessionStatus =
| 'pending'
| 'processing'
| 'requires_action'
| 'captured'
| 'failed'
| 'cancelled'
| 'refunded'
Delivery Types
DeliveryProvider
The pluggable interface for last-mile delivery services:
interface DeliveryProvider {
estimate(input: EstimateDeliveryInput): Promise<DeliveryEstimate>
createDelivery(input: CreateDeliveryInput): Promise<Delivery>
getDelivery(deliveryId: string): Promise<Delivery>
cancelDelivery(deliveryId: string): Promise<Delivery>
verifyWebhook(payload: string | Uint8Array, signature: string): Promise<DeliveryWebhookEvent>
}
Delivery & DeliveryEstimate
interface Delivery {
id: string
status: DeliveryStatus
orderId?: string
trackingUrl?: string
driver?: { name: string; phone: string; latitude: number; longitude: number }
createdAt: string
}
type DeliveryStatus = 'pending' | 'assigned' | 'pickup' | 'in_transit' | 'delivered' | 'cancelled' | 'failed'
interface DeliveryEstimate {
fee: number
currency: string
estimatedDuration: number // minutes
}
Storage Types
StorageProvider
The pluggable interface for object storage:
interface StorageProvider {
upload(input: UploadInput): Promise<StorageUploadResult>
delete(key: string): Promise<void>
getUrl(key: string): string
getPresignedUploadUrl(key: string, options?: PresignedUrlOptions): Promise<PresignedUrlResult>
getPresignedDownloadUrl(key: string, options?: PresignedUrlOptions): Promise<PresignedUrlResult>
}
interface StorageUploadResult {
key: string
url: string
}
Adapter Contract
The CommerceAdapter uses a flat API — all domain methods are directly on the adapter object:
interface CommerceAdapter {
name: string
capabilities: AdapterDomain[]
// Catalog
getProduct(id: string): Promise<Product>
getProducts(params?: GetProductParams): Promise<PaginatedResult<Product>>
getCategories(params?: GetCategoriesParams): Promise<Category[]>
// Cart
createCart(): Promise<Cart>
getCart(id: string): Promise<Cart>
addToCart(cartId: string, input: AddToCartInput): Promise<Cart>
updateCartItem(cartId: string, itemId: string, quantity: number): Promise<Cart>
removeFromCart(cartId: string, itemId: string): Promise<Cart>
// Orders
createOrder(input: CreateOrderInput): Promise<Order>
getOrder(id: string): Promise<Order>
getCustomerOrders(customerId: string): Promise<Order[]>
// Customers
login(email: string, password: string): Promise<Customer>
register(input: RegisterInput): Promise<Customer>
getCustomer(id: string): Promise<Customer>
// ... wishlist, reviews, store, promotions, returns, etc.
}
Adapters declare which domains they support via the capabilities array. Unsupported domain methods throw CommerceError with code NOT_SUPPORTED.
Error Handling
import { CommerceError, isCommerceError } from '@commercejs/types'
try {
const product = await adapter.getProduct('invalid-id')
} catch (err) {
if (isCommerceError(err)) {
console.log(err.code) // 'NOT_FOUND'
console.log(err.message) // 'Product not found'
}
}
Available error codes: NOT_FOUND, VALIDATION_ERROR, UNAUTHORIZED, RATE_LIMITED, PROVIDER_ERROR, NOT_IMPLEMENTED.
Orchestrator Types
The three-tier domain model for composable commerce:
import type {
CommerceOrchestrator,
UniversalDomains,
CommonDomains,
SpecializedDomains,
DomainMap,
} from '@commercejs/types'
// Universal — always required
interface UniversalDomains {
catalog: CatalogAdapter
store: StoreAdapter
}
// Common — optional but widely needed
interface CommonDomains {
cart?: CartAdapter
checkout?: CheckoutAdapter
orders?: OrderAdapter
customers?: CustomerAdapter
// ... wishlist, reviews, promotions, brands, countries, locations
}
// Specialized — niche domains
interface SpecializedDomains {
returns?: ReturnAdapter
wholesale?: WholesaleAdapter
auctions?: AuctionAdapter
rentals?: RentalAdapter
giftCards?: GiftCardAdapter
}
// The orchestrator provides type-safe domain access
interface CommerceOrchestrator extends UniversalDomains {
readonly name: string
readonly capabilities: AdapterDomain[]
supports(domain: string): boolean
domain<D extends keyof DomainMap>(key: D): DomainMap[D]
}
Provider Types
NotificationProvider
interface NotificationProvider {
readonly id: string
readonly name: string
readonly channels: NotificationChannel[]
send(channel: NotificationChannel, message: NotificationMessage): Promise<NotificationResult>
}
type NotificationChannel = 'email' | 'sms' | 'push_web' | 'push_mobile' | 'whatsapp' | 'telegram'
AnalyticsProvider
interface AnalyticsProvider {
readonly id: string
readonly name: string
track(event: string, properties?: Record<string, unknown>): void
identify(userId: string, traits?: Record<string, unknown>): void
page(name: string, properties?: Record<string, unknown>): void
}
TaxProvider
interface TaxProvider {
readonly id: string
readonly name: string
calculate(input: TaxCalculationInput): Promise<TaxResult>
commit(orderId: string, transactionId: string): Promise<void>
void(transactionId: string): Promise<void>
}