Order & Payment Approval
This guide walks an admin through what happens on the admin channel when a customer submits an order, and how to approve or reject the payment from inside Discord.
What you see when an order is submitted
When a guild member confirms an order via /order, two things happen immediately:
- A DM goes to the customer with their order number and payment instructions for the method they picked.
- An admin-channel embed is posted to the channel configured as
announcementChannelId(oradminChannelIdas a fallback) on the tenant'sBotConfig.
The admin-channel embed looks like this:
- Title:
Payment Awaiting Approval — Order <orderNumber> - Fields: Customer mention, payment method, amount, payment ID, and the customer's reference note (typically the order number).
- Two buttons: Approve Payment (green) and Reject Payment (red).
Approving a payment
Click Approve Payment. The bot:
- Verifies you hold an admin role (fails with an ephemeral error otherwise).
- Transitions the payment from
awaiting_admin_approval→confirmed. - Emits
payment.confirmed. The notifications consumer then DMs the customer "Payment received!" and the order moves into fulfillment. - Posts an ephemeral confirmation to you and a thread message in the order channel so other staff see the action.
If you click twice, the second click is a no-op — only the first transition wins.
Rejecting a payment
Click Reject Payment. A modal opens asking for a rejection reason.
When you submit the modal:
- Admin role is re-verified.
- The payment transitions to
rejectedand emitspayment.rejected. - The order consumer releases the inventory reservation and transitions the order to
CANCELLED. - The notifications consumer DMs the customer with the rejection reason and posts an audit entry to the admin channel.
The reject reason is stored on the payment record (rejectionReason) for the audit trail.
Operational notes
- Idempotency. Both approve and reject are idempotent at the service layer. If a duplicate event is delivered, the second delivery is a no-op.
- Role gating. Only members with a role listed in
BotConfig.adminRoleIdscan approve or reject. - Audit trail. Every transition updates
approverUserId,approvedAt/rejectedAt, andrejectionReason(when rejected). Cancelled orders gain a note line onOrder.notes. - Refunds. For already-approved payments, use
/refundto reverse — see the Order Management guide.