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

  • Orderz.infer<typeof orderSchema>
  • OrderCreateInputz.infer<typeof orderCreateInputSchema>
  • OrderPatchInputz.infer<typeof orderPatchInputSchema>
  • OrderItemz.infer<typeof orderItemSchema>
  • OrderStatusz.infer<typeof orderStatusSchema>