Spaces:
Sleeping
Sleeping
Expense Payment Routing - Agent vs Vendor
Overview
Expenses support two payment flows:
- Agent Reimbursement: Agent pays with own money, gets reimbursed
- Vendor Direct Payment: Company pays vendor directly (e.g., petrol stations, suppliers)
API Endpoint
POST /api/v1/ticket-expenses
Payment Recipient Types
type PaymentRecipientType = "agent" | "vendor"
Payment Methods
type PaymentMethod =
| "send_money" // M-Pesa Send Money (personal)
| "till_number" // M-Pesa Buy Goods (Till)
| "paybill" // M-Pesa Paybill
| "pochi_la_biashara" // M-Pesa Business Wallet
| "bank_transfer" // Bank account
| "cash" // Cash payment
Use Case 1: Agent Reimbursement (Default)
When: Agent paid with own money (taxi, meals, small purchases)
Request: Omit payment fields - system auto-populates from agent's financial account
{
"ticket_assignment_id": "uuid",
"category": "transport",
"description": "Taxi to customer site",
"expense_date": "2024-12-13",
"total_cost": 500.00
}
System Behavior:
- Sets
payment_recipient_type: "agent" - Auto-fills
payment_methodandpayment_detailsfrom agent's primary financial account - If no financial account exists, leaves null (PM handles manually)
Use Case 2: Vendor Direct Payment
When: High-value expenses, vendor requires direct payment (fuel, materials, equipment)
Request: Provide payment routing details
Example 1: Petrol Station (Till Number)
{
"ticket_assignment_id": "uuid",
"category": "transport",
"description": "Fuel for generator - 50 liters",
"expense_date": "2024-12-13",
"quantity": 50,
"unit": "liters",
"unit_cost": 150.00,
"total_cost": 7500.00,
"payment_recipient_type": "vendor",
"payment_method": "till_number",
"payment_details": {
"till_number": "123456",
"business_name": "Shell Petrol Station"
}
}
Example 2: Hardware Store (Paybill)
{
"ticket_assignment_id": "uuid",
"category": "materials",
"description": "Electrical cables and switches",
"expense_date": "2024-12-13",
"total_cost": 12000.00,
"payment_recipient_type": "vendor",
"payment_method": "paybill",
"payment_details": {
"business_number": "888888",
"account_number": "ACC123",
"business_name": "ABC Hardware"
}
}
Example 3: Supplier (Bank Transfer)
{
"ticket_assignment_id": "uuid",
"category": "materials",
"description": "Bulk cement order",
"expense_date": "2024-12-13",
"total_cost": 45000.00,
"payment_recipient_type": "vendor",
"payment_method": "bank_transfer",
"payment_details": {
"bank_name": "Equity Bank",
"account_number": "0123456789",
"account_name": "XYZ Supplies Ltd",
"branch": "Industrial Area"
}
}
Payment Details Schema by Method
send_money (M-Pesa Personal)
{
phone_number: string // Format: +254XXXXXXXXX
recipient_name: string
}
till_number (M-Pesa Buy Goods)
{
till_number: string // 5-7 digits
business_name: string
}
paybill (M-Pesa Paybill)
{
business_number: string // 5-7 digits
account_number: string
business_name: string
}
pochi_la_biashara (M-Pesa Business Wallet)
{
phone_number: string // Format: +254XXXXXXXXX
business_name: string
}
bank_transfer
{
bank_name: string
account_number: string
account_name: string
branch?: string // Optional
}
cash
{
recipient_name: string
id_number?: string // Optional
}
UI Recommendations
Step 1: Who Paid?
[ ] I paid (reimbursement)
[ ] Pay vendor directly
Step 2: If "Pay vendor directly" selected
Show payment method selector:
[ ] M-Pesa Till Number (Buy Goods)
[ ] M-Pesa Paybill
[ ] Bank Transfer
[ ] M-Pesa Business Wallet
[ ] Cash
Step 3: Collect method-specific details
Dynamic form based on selected payment method
Validation Rules
- Agent Reimbursement: No payment fields required
- Vendor Payment: All three fields required:
payment_recipient_type: "vendor"payment_method: <method>payment_details: <complete details>
- Phone numbers: Must match
+254[17]XXXXXXXX - Till/Paybill numbers: 5-7 digits
- All text fields: Non-empty strings
Common Scenarios
| Expense Type | Typical Amount | Recommended Flow |
|---|---|---|
| Taxi/Transport | < 2,000 | Agent pays |
| Meals | < 1,000 | Agent pays |
| Fuel | > 5,000 | Pay vendor |
| Materials | > 10,000 | Pay vendor |
| Equipment | > 20,000 | Pay vendor |
| Small supplies | < 5,000 | Agent pays |
Response
Same response for both flows:
{
"id": "uuid",
"ticket_assignment_id": "uuid",
"category": "transport",
"description": "...",
"total_cost": 500.00,
"payment_recipient_type": "agent", // or "vendor"
"payment_method": "send_money",
"payment_details": { ... },
"is_approved": false,
"is_paid": false,
...
}
Notes
- Agent financial account must be set up for auto-population to work
- Vendor payments require complete details upfront
- Both flows go through same approval process
- Payment export generates Tende Pay compatible CSV