Files
dashboards/apps/business/src/services/orderService.ts
T
Alireza HassaniandCursor bc1c5f0747 Show transaction ID and gateway refs in order payment details.
Surface Meshkee transaction id, ZarinPal track/authority, card pan, and paid time in the transactions modal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-02 22:15:12 +03:30

185 lines
4.7 KiB
TypeScript

import { apiRequest } from '../lib/api'
import { getActiveBusinessId } from '../lib/businessContext'
export type OrderStatus =
| 'pending'
| 'confirmed'
| 'processing'
| 'shipped'
| 'delivered'
| 'cancelled'
export type OrderSource = 'website' | 'admin' | 'app'
export interface OrderItem {
id: string
storeItemVariantId: string | null
productId: string
productTitle: string
productImage: string | null
variantSku: string | null
unitPrice: number
compareAtPrice: number | null
quantity: number
lineTotal: number
selections: {
variationId: string
variationName: string
optionId: string
value: string
}[]
}
export interface OrderCustomer {
id: string
firstName: string | null
lastName: string | null
cellNumber: string
email: string | null
}
export type TransactionType = 'pos' | 'cash' | 'transfer' | 'e_payment_gate'
export type TransactionStatus = 'pending' | 'completed' | 'failed' | 'refunded'
export interface OrderTransaction {
id: string
type: TransactionType
status: TransactionStatus
amount: number
posType: string | null
gatewayType: string | null
gatewayRef: string | null
gatewayTrackId: string | null
cardPan: string | null
paidAt: string | null
transferAccount: string | null
transferRefNumber: string | null
notes: string | null
createdBy: string | null
createdAt: string
updatedAt: string
}
export interface Order {
id: string
businessId: string
orderNumber: string
status: OrderStatus
processStepId: string
processStepLabel?: string | null
processStepLabelFa?: string | null
processStepColor?: string | null
source: OrderSource
subtotal: number
shippingTotal: number
discountTotal: number
total: number
shippingAddress: Record<string, unknown>
addressId: string | null
customerNotes: string | null
adminNotes: string | null
createdBy: string | null
createdAt: string
updatedAt: string
customer: OrderCustomer
items: OrderItem[]
transactions?: OrderTransaction[]
}
export interface OrdersListResponse {
items: Order[]
total: number
page: number
pageSize: number
}
export interface ListOrdersParams {
page?: number
pageSize?: number
status?: OrderStatus
orderNumber?: string
customerQuery?: string
dateFrom?: string
dateTo?: string
minTotal?: number
maxTotal?: number
}
export interface CreateAdminOrderPayment {
type: 'pos' | 'cash' | 'transfer' | 'e_payment_gate'
amount: number
posType?: string
gatewayType?: string
transferAccount?: string
transferRefNumber?: string
notes?: string
}
export interface CreateAdminOrderPayload {
customerUserId: string
items: { storeItemVariantId: string; quantity: number }[]
customerNotes?: string
adminNotes?: string
status?: OrderStatus
payments?: CreateAdminOrderPayment[]
}
function businessPath(suffix = '') {
const businessId = getActiveBusinessId()
if (!businessId) {
throw new Error('No active business selected. Please sign in again.')
}
return `/businesses/${businessId}/orders${suffix}`
}
export async function listOrders(params: ListOrdersParams = {}, signal?: AbortSignal) {
const q = new URLSearchParams()
if (params.page !== undefined) q.set('page', String(params.page))
if (params.pageSize !== undefined) q.set('pageSize', String(params.pageSize))
if (params.status) q.set('status', params.status)
if (params.orderNumber) q.set('orderNumber', params.orderNumber)
if (params.customerQuery) q.set('customerQuery', params.customerQuery)
if (params.dateFrom) q.set('dateFrom', params.dateFrom)
if (params.dateTo) q.set('dateTo', params.dateTo)
if (params.minTotal !== undefined) q.set('minTotal', String(params.minTotal))
if (params.maxTotal !== undefined) q.set('maxTotal', String(params.maxTotal))
const query = q.toString()
const path = `${businessPath()}${query ? `?${query}` : ''}`
return apiRequest<OrdersListResponse>(path, { auth: true, signal })
}
export async function getOrder(orderId: string, signal?: AbortSignal) {
return apiRequest<{ order: Order }>(businessPath(`/${orderId}`), { auth: true, signal })
}
export async function createAdminOrder(payload: CreateAdminOrderPayload) {
return apiRequest<{ message: string; order: Order }>(businessPath(), {
method: 'POST',
auth: true,
body: payload,
})
}
export async function removeOrder(orderId: string) {
return apiRequest<{ message: string }>(businessPath(`/${orderId}`), {
method: 'DELETE',
auth: true,
})
}
export interface UpdateOrderPayload {
processStepId?: string
status?: OrderStatus
adminNotes?: string
}
export async function updateOrder(orderId: string, payload: UpdateOrderPayload) {
return apiRequest<{ message: string; order: Order }>(businessPath(`/${orderId}`), {
method: 'PATCH',
auth: true,
body: payload,
})
}