Skip to main content

Discord Order Flow Commands

The Discord order flow is a multi-step conversational ordering process driven by slash commands and message components (buttons, select menus, modals). Commands are routed through createDiscordOrderCommandRouter (defined in src/data/order/order.command.ts) and wired to HTTP via src/endpoints/discord.endpoint.ts.

Each command operates on an order session — a stateful record that tracks items, shipping, and payment as the user progresses through the flow. Sessions expire after 30 minutes of inactivity. The flow supports rich UX: /order-start returns an embed with a "Browse products" button; /product-list shows products with Add buttons; shipping can reuse saved addresses (select menu, confirm, edit) or open an address modal.

Session State Machine

COLLECTING_ITEMS → COLLECTING_SHIPPING → SELECTING_PAYMENT → READY_TO_SUBMIT → SUBMITTED

Commands

/register

Description: Starts a new order session (alias for /order-start). If the user already has an active session it is returned instead of creating a duplicate.

Permissions: Any Discord user in a guild linked to a tenant.

Parameters:

NameTypeRequiredDescription
(none)No parameters required.

Example: /register


/order-start

Description: Begins a new order session. Functionally identical to /register. Creates a session in the COLLECTING_ITEMS state. Returns an embed with a "Browse products" button that opens the product list.

Permissions: Any Discord user in a guild linked to a tenant.

Parameters:

NameTypeRequiredDescription
(none)No parameters required.

Example: /order-start


/order-item

Description: Adds an item to the active order session. Advances the session state to COLLECTING_SHIPPING once the first item is added.

Permissions: Session owner (the Discord user who started the session).

Parameters:

NameTypeRequiredDescription
productIdstringYesThe product identifier to add.
namestringYesDisplay name of the product.
skustringYesSKU code for the product variant.
quantitynumberYesNumber of units to add.
unitPriceCentsnumberYesPrice per unit in cents.
currencystringYesISO 4217 currency code (e.g. USD).

Example: /order-item productId:prod_123 name:Widget sku:WDG-001 quantity:2 unitPriceCents:1500 currency:USD


/order-shipping

Description: Captures the shipping address for the active session. Requires at least one item to have been added first. If the customer has saved addresses, a select menu is shown; the user can confirm, edit, or add new. Otherwise, a modal form is presented. Advances the session state to SELECTING_PAYMENT.

Permissions: Session owner.

Parameters:

NameTypeRequiredDescription
(options)objectYesShipping address fields (street, city, state, zip, country, etc.) passed as command options.

Example: /order-shipping street:123 Main St city:Springfield state:IL zip:62701 country:US


/order-payment

Description: Sets the payment method for the active session. Advances the session state to READY_TO_SUBMIT.

Permissions: Session owner.

Parameters:

NameTypeRequiredDescription
paymentMethodstringYesOne of: PAYPAL, CASHAPP_PAY, BTC_INVOICE, VENMO_P2P, CASHAPP_P2P, ZELLE, CHIME, PAYPAL_MANUAL, BTC_MANUAL.

Example: /order-payment paymentMethod:CASHAPP_PAY


/order-submit

Description: Submits the completed order. Creates the order record, initiates payment, reserves inventory, and returns payment instructions to the user. The session state moves to SUBMITTED.

Permissions: Session owner.

Parameters:

NameTypeRequiredDescription
(none)No parameters required.

Example: /order-submit


/payment-confirm

Description: Confirms that payment has been received for a submitted order. Typically used by a store operator or admin after verifying funds.

Permissions: Tenant member with payment confirmation access.

Parameters:

NameTypeRequiredDescription
orderIdstringYesThe order identifier to confirm payment for.

Example: /payment-confirm orderId:ord_abc123


/refund

Description: Refunds an order, fully or partially. A full refund reverts all inventory and revokes all entitlements. Partial refunds can be applied incrementally until the cumulative refunded amount equals the order total.

Permissions: Admin.

Parameters:

NameTypeRequiredDescription
orderstringYesThe order identifier to refund.
reasonstringNoReason for the refund. Defaults to "Admin-initiated refund".
amountintegerNoAmount to refund in cents. When provided without items: adjusts the payment balance only (no inventory change). Mutually exclusive with items in a single command.
itemsstringNoComma-separated productId:quantity pairs (e.g. prod-1:2,prod-2:1). Quantity defaults to 1. Reverts inventory and revokes entitlements for those items. Derives the refund amount from quantity × unitPriceCents. Mutually exclusive with amount.

Design decision: Providing both amount and items in a single slash command is rejected with an error message. Admins who need to specify both (custom amount + specific item inventory revert) should use the AdminJS panel, which supports a richer multi-step refund form.

Examples:

# Full refund
/refund order:ord_abc123 reason:Customer request

# Partial by amount (no inventory change — customer keeps the product)
/refund order:ord_abc123 reason:Damage compensation amount:500

# Partial by items (inventory reverted, amount derived from item prices)
/refund order:ord_abc123 reason:Returned items items:prod-1:2,prod-2:1

Typical Flow

1. /register → Session created (COLLECTING_ITEMS)
2. /order-item ... → Item added (COLLECTING_SHIPPING)
3. /order-shipping ... → Address set (SELECTING_PAYMENT)
4. /order-payment ... → Method set (READY_TO_SUBMIT)
5. /order-submit → Order placed (SUBMITTED)
6. /payment-confirm ... → Payment verified

Sources

  • Command router: src/data/order/order.command.ts
  • Command constants: src/data/order/order.constants.ts
  • Order-flow service factory: src/data/order/order-flow.factory.ts
  • Order session service: src/data/order-session/order-session.service.ts
  • Discord endpoint wiring: src/endpoints/discord.endpoint.ts