Skip to main content

Order

Source: src/data/order/

Service​

createOrderService / OrderService​

Factory: createOrderService(orderRepository: OrderRepository, discountService: OrderDiscountService) — returns OrderService.

Creates order service with discount-aware deterministic pricing.

MethodParametersReturnsDescription
create(ctx: RequestContext, input: OrderCreateInput)Promise<OrderRecord>Creates an order with deterministic pricing and idempotent replay behavior; evaluates and consumes discount if provided
getById(ctx: RequestContext, id: string)Promise<OrderRecord | null>Returns an order by id for the current tenant
update(ctx: RequestContext, id: string, patch: OrderPatchInput)Promise<OrderRecord>Patches an existing order
remove(ctx: RequestContext, id: string)Promise<void>Deletes an order by id
listByTenant(ctx: RequestContext)Promise<OrderRecord[]>Lists tenant orders
listOpenOrders(ctx: RequestContext, filters: ListOpenOrdersInput)Promise<OpenOrderListResult>Returns paginated open orders for the dashboard. Fails closed if tenantId is empty.
getOpenOrderSummary(ctx: RequestContext)Promise<OpenOrderSummary>Returns per-status open-order counts. Fails closed if tenantId is empty.

createDiscordOrderFlowServiceWithDeps / DiscordOrderFlowService​

Factory: createDiscordOrderFlowServiceWithDeps(deps) — returns DiscordOrderFlowService.

File: order-flow.service.ts

Creates tenant-aware Discord order flow orchestration across session, order, payment, inventory, discount, notification, and event-bus domains.

Dependencies:

  • orderSessionService: OrderSessionService
  • orderService: OrderService
  • paymentService: PaymentService
  • inventoryService: InventoryService
  • botConfigService: Pick<BotConfigService, 'resolvePaymentInstruction' | 'listShippingTypes'>
  • adminNotificationService: AdminNotificationService
  • discountService?: Pick<DiscountService, 'resolveBestForCustomer' | 'consumeAssignmentUsage'>
  • customerService?: Pick<CustomerService, 'findByDiscordId' | 'addAddress'>
  • eventBus?: Pick<EventBus, 'emit'> — when present, the flow emits order.created so the notifications consumer can post the admin approval embed and DM the customer.
MethodParametersReturnsDescription
beginSession(ctx, { discordUserId, guildId? })Promise<{ state: string }>Creates or restores an active order capture session.
getActiveSession(ctx, discordUserId)Promise<OrderSessionRecord | null>Returns the active session for a Discord user.
selectProduct(ctx, { discordUserId, productId })Promise<{ state: string }>Records the chosen product (pre-quantity).
addItem(ctx, { discordUserId, item })Promise<{ state, itemCount }>Adds an item (with quantity) and advances state.
setShipping(ctx, { discordUserId, shippingAddress })Promise<{ state: string }>Stores the shipping address and advances to shipping-type selection.
proposeCorrectedAddress(ctx, { discordUserId, correctedAddress })Promise<{ state: string }>Stores a validator-corrected suggestion awaiting customer choice.
acceptCorrectedAddress(ctx, { discordUserId })Promise<{ state: string }>Customer accepted the corrected address.
keepOriginalAddress(ctx, { discordUserId })Promise<{ state: string }>Customer kept their original address.
setShippingType(ctx, { discordUserId, shippingType })Promise<{ state: string }>Stores shipping carrier/type and cost; advances to payment selection.
setPaymentMethod(ctx, { discordUserId, paymentMethod })Promise<{ state, paymentMethod }>Stores payment method and advances to AWAITING_CONFIRMATION.
cancelSession(ctx, { discordUserId })Promise<void>Cancels the active session.
submit(ctx, { discordUserId })Promise<OrderFlowSummary>Resolves best discount, creates order + payment record, calls paymentService.submitForApproval, reserves inventory, emits order.created. Idempotent on replay.
confirmPayment(ctx, { orderId, confirmedBy })Promise<void>Confirms payment and finalizes the sale.
handlePaymentRejected(ctx, { orderId, reason? })Promise<void>Releases inventory reservations and transitions order to CANCELLED. Idempotent.

OrderFlowSummary​

Shape returned by submit:

FieldTypeDescription
orderIdstringCreated order id.
orderNumberstringTenant-facing order number.
paymentIdstringPending payment id.
paymentMethodPaymentMethodPayment method selected.
paymentInstructionsstringPer-method instructions from bot config.
subtotalCentsnumberPre-discount item total.
shippingCostCentsnumberSelected shipping-type cost.
discountAmountCentsnumberAmount discounted from subtotal.
taxAmountCentsnumberSales tax in cents; 0 when TaxJar is not configured or no shipping address.
totalCentsnumberFinal total: (subtotal − discount) + shipping + tax.
currencystringOrder currency.
referenceCodestringShort reference shown to the customer.

registerOrderPaymentConsumers​

File: order.consumers.ts

Registers payment.rejected on the event bus. When an admin rejects a payment, the consumer calls orderFlow.handlePaymentRejected to release inventory and transition the order to CANCELLED. Wired by src/registries/events.registry.ts.

Repository​

OrderRepository​

MethodParametersReturns
getById(ctx: RequestContext, id: string)Promise<OrderRecord | null>
findByOrderNumber(ctx: RequestContext, orderNumber: string)Promise<OrderRecord | null>
listByTenant(ctx: RequestContext)Promise<OrderRecord[]>
create(ctx: RequestContext, input: Omit<OrderRecord, 'createdAt' | 'updatedAt'>)Promise<OrderRecord>
update(ctx: RequestContext, id: string, patch: OrderPatchInput)Promise<OrderRecord>
delete(ctx: RequestContext, id: string)Promise<void>
listByCustomerId(ctx: RequestContext, customerId: string)Promise<OrderRecord[]>
reassignCustomer(ctx: RequestContext, fromCustomerId: string, toCustomerId: string)Promise<number>

Validators​

orderStatusSchema​

Enum: PENDING_PAYMENT, PAID, FULFILLING, SHIPPED, COMPLETE, CANCELLED, REFUNDED, PARTIALLY_REFUNDED

PARTIALLY_REFUNDED is a closed status (excluded from the Open Orders dashboard). It is set when one or more partial refunds have been applied but the cumulative refunded amount has not yet reached the order total. When the cumulative total reaches the order amount, the status transitions to REFUNDED.

orderItemSchema​

FieldTypeRequiredDefault
productIdstringYes—
namestringYes—
skustringYes—
quantitynumber (int, positive)Yes—
unitPriceCentsnumber (int, ≥ 0)Yes—
currencycurrencySchemaYes—

orderCustomerSchema​

FieldTypeRequiredDefault
namestringYes—
emailstring (email)No—
discordIdstringNo—

orderSchema​

FieldTypeRequiredDefault
tenantIdstringYes—
orderNumberstringYes—
statusorderStatusSchemaYes—
itemsorderItemSchema[] (min 1)Yes—
subtotalCentsnumber (int, ≥ 0)Yes—
totalCentsnumber (int, ≥ 0)Yes—
discountIdstringNo—
discountCodestringNo—
discountAmountCentsnumber (int, ≥ 0)No0
currencycurrencySchemaYes—
customerorderCustomerSchemaYes—
customerIdstringNo—
customerRoleIdsstring[]No[]
shippingAddressaddressSchemaNo—
shippingStatusenum('PENDING', 'LABEL_CREATED', 'SHIPPED', 'DELIVERED', 'FAILED')No'PENDING'
shipmentIdstringNo—
trackingNumberstringNo—
notesstringNo—
createdAtDate (coerced)Yes—
updatedAtDate (coerced)Yes—

orderCreateInputSchema​

Omits tenantId, subtotalCents, totalCents, discountId, discountAmountCents from base. status and shippingStatus are optional. Adds optional discountCode.

orderPatchInputSchema​

All fields from base except tenantId and orderNumber, made partial.

Inferred Types​

  • Order — z.infer<typeof orderSchema>
  • OrderCreateInput — z.infer<typeof orderCreateInputSchema>
  • OrderPatchInput — z.infer<typeof orderPatchInputSchema>
  • OrderItem — z.infer<typeof orderItemSchema>
  • OrderStatus — z.infer<typeof orderStatusSchema>