Skip to main content

Partner Submit Payment on Inventory Orders

Overview

Partners can submit payments against their inventory orders directly from the partner portal. When a payment is submitted, it is created with a Pending status and linked to the inventory order via the createPaymentAndLinkWorkflow.

Architecture

Partner UI (RouteDrawer form)


POST /partners/inventory-orders/:orderId/submit-payment

├─ Auth: getPartnerFromAuthContext()
├─ Validation: Zod safeParse (inline schema)


createPaymentAndLinkWorkflow
├─ createPaymentStep (status: "Pending")
└─ linkPaymentToInventoryOrdersStep (links payment ↔ order)

Backend

API Route

File: src/api/partners/inventory-orders/[orderId]/submit-payment/route.ts

Method: POST

Authentication: Partner session or bearer token via getPartnerFromAuthContext().

Request Body:

FieldTypeRequiredDefaultDescription
amountnumberYesPayment amount (must be > 0)
payment_typeenumNo"Cash""Bank", "Cash", or "Digital_Wallet"
payment_datedateNonowWhen the payment was made
notestringNoOptional note attached as metadata
paid_to_idstringNoID of a saved payment method to link

Response:

{
"message": "Payment submitted successfully",
"payment": { "id": "...", "amount": 5000, "status": "Pending", ... }
}

Error Responses:

  • 400 — Invalid request body (Zod validation errors)
  • 401 — Partner authentication required
  • 500 — Workflow execution failure

Middleware

File: src/api/middlewares.ts

Entry added alongside the existing start/complete routes:

{
matcher: "/partners/inventory-orders/:orderId/submit-payment",
method: "POST",
middlewares: [
authenticate("partner", ["session", "bearer"]),
],
}

Workflow

Uses the existing createPaymentAndLinkWorkflow from src/workflows/internal_payments/create-payment-and-link.ts. This workflow:

  1. createPaymentStep — Creates an internal payment record with the given amount, type, date, and status: "Pending"
  2. linkPaymentToInventoryOrdersStep — Creates a remote link between the payment and the inventory order via ORDER_INVENTORY_MODULE ↔ INTERNAL_PAYMENTS_MODULE

Frontend

Mutation Hook

File: apps/partner-ui/src/hooks/api/partner-inventory-orders.tsx

useSubmitPartnerInventoryOrderPayment(orderId)
  • POSTs to /partners/inventory-orders/${orderId}/submit-payment
  • On success, invalidates both the detail and list query caches

RouteDrawer Page

File: apps/partner-ui/src/routes/inventory-orders/inventory-order-submit-payment/inventory-order-submit-payment.tsx

Form fields:

FieldComponentBehavior
AmountInputPre-filled from inventoryOrder.total_price
Payment DateDatePickerDefaults to today
Payment MethodSelectLoads from usePartnerPaymentMethods(partnerId), shows loading state
NoteTextareaOptional

Payment type derivation: When a saved payment method is selected, the payment_type is automatically derived:

Method TypePayment Type
bank_accountBank
cash_accountCash
digital_walletDigital_Wallet
None selectedCash (default)

Route Registration

File: apps/partner-ui/src/dashboard-app/routes/get-partner-route.map.tsx

Added as a child of /inventory-orders/:id:

{
path: "submit-payment",
lazy: () => import("../../routes/inventory-orders/inventory-order-submit-payment"),
}

Action Button

File: apps/partner-ui/src/routes/inventory-orders/inventory-order-detail/components/inventory-order-actions-section.tsx

A "Submit Payment" button (secondary variant) is shown when partner_started_at is set — meaning the partner has started working on the order. This allows payment submission for both in-progress and completed orders.

Files Summary

#ActionFile
1Createsrc/api/partners/inventory-orders/[orderId]/submit-payment/route.ts
2Modifysrc/api/middlewares.ts
3Modifyapps/partner-ui/src/hooks/api/partner-inventory-orders.tsx
4Createapps/partner-ui/src/routes/inventory-orders/inventory-order-submit-payment/inventory-order-submit-payment.tsx
5Createapps/partner-ui/src/routes/inventory-orders/inventory-order-submit-payment/index.ts
6Modifyapps/partner-ui/src/dashboard-app/routes/get-partner-route.map.tsx
7Modifyapps/partner-ui/src/routes/inventory-orders/inventory-order-detail/components/inventory-order-actions-section.tsx

Patterns Reused

PatternSource File
Route auth + manual Zod validationsrc/api/partners/inventory-orders/[orderId]/complete/route.ts
RouteDrawer action pageapps/partner-ui/src/routes/inventory-orders/inventory-order-start/
Payment method select + type derivationsrc/admin/routes/inventory/orders/[id]/@add-payments/page.tsx
Mutation hook with cache invalidationapps/partner-ui/src/hooks/api/partner-inventory-orders.tsx