7.7 KiB
Settlement & Wallet API
Prefix:
/api/v1/wallet,/api/v1/settlement
GET /api/v1/wallet/balance
Get authenticated user's wallet balance.
Permission: AUTH
Response 200
{
"success": true,
"data": {
"balance_rials": 2500000,
"recent_transactions": [
{
"uuid": "...",
"type": "credit",
"amount_rials": 500000,
"balance_after": 2500000,
"description": "دریافت از نوبت شماره ...",
"created_at": 1717000000
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
GET /api/v1/wallet/transactions
Get wallet transaction history for the authenticated user.
Permission: AUTH
Response 200
{
"success": true,
"data": [
{
"uuid": "...",
"type": "credit",
"amount_rials": 500000,
"balance_after": 2500000,
"description": "دریافت از نوبت",
"created_at": 1717000000
},
{
"uuid": "...",
"type": "debit",
"amount_rials": 200000,
"balance_after": 2300000,
"description": "تسویهحساب",
"created_at": 1716900000
}
]
}
Transaction Type Values:
| Value | Description |
|---|---|
credit |
Money added to wallet |
debit |
Money removed from wallet |
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
POST /api/v1/settlement
Request a settlement (withdrawal from wallet to bank account).
Permission: AUTH
Request Body (application/json)
{
"amount_rials": 1000000,
"bank_account": {
"iban": "IR...",
"account_number": "1234567890",
"bank_name": "بانک ملت",
"owner_name": "علی احمدی"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
amount_rials |
integer | ✅ | Amount to withdraw (must be ≤ wallet balance) |
bank_account |
object | ❌ | Bank account details (saved if not previously set) |
bank_account.iban |
string | ❌ | IBAN (شبا) |
bank_account.account_number |
string | ❌ | Account number |
bank_account.bank_name |
string | ❌ | Bank name |
bank_account.owner_name |
string | ❌ | Account owner name |
Response 201
{
"success": true,
"data": {
"uuid": "settle-uuid-...",
"amount_rials": 1000000,
"status": "pending",
"bank_account": {
"iban": "IR...",
"bank_name": "بانک ملت",
"owner_name": "علی احمدی"
},
"created_at": 1717000000
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_VALIDATION_001 |
422 | Amount exceeds balance or invalid amount |
GET /api/v1/settlement
Get authenticated user's settlement requests.
Permission: AUTH
Response 200
{
"success": true,
"data": [
{
"uuid": "...",
"amount_rials": 1000000,
"status": "pending",
"note": null,
"created_at": 1717000000,
"processed_at": null
}
]
}
Settlement Status Values:
| Value | Description |
|---|---|
pending |
Awaiting admin review |
approved |
Approved, payment sent |
rejected |
Rejected by admin |
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
GET /api/v1/settlement/{uuid}
Get a single settlement.
Permission: AUTH — must be the owner or ROLE_ADMIN
Response 200
Settlement object with full details including bank_account.
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_FORBIDDEN_001 |
403 | Not the owner |
ERR_NOT_FOUND_001 |
404 | Settlement not found |
POST /api/v1/settlement/{uuid}/approve
Approve a settlement request. Marks it as paid and debits the wallet.
Permission: ROLE_ADMIN
Path Parameters
| Param | Type | Description |
|---|---|---|
uuid |
string (UUID) | Settlement UUID |
Request Body (application/json)
{
"note": "پرداخت شد — شناسه پیگیری: 123456"
}
| Field | Type | Required |
|---|---|---|
note |
string | ❌ |
Response 200
Updated settlement object with status: "approved".
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_AUTH_006 |
403 | Not admin |
ERR_NOT_FOUND_001 |
404 | Settlement not found |
ERR_VALIDATION_001 |
422 | Already processed |
POST /api/v1/settlement/{uuid}/reject
Reject a settlement request. Returns the amount back to wallet.
Permission: ROLE_ADMIN
Request Body
{
"note": "حساب بانکی نادرست است"
}
| Field | Type | Required |
|---|---|---|
note |
string | ✅ |
Response 200
Updated settlement object with status: "rejected".
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_AUTH_006 |
403 | Not admin |
ERR_NOT_FOUND_001 |
404 | Settlement not found |
ERR_VALIDATION_002 |
422 | Missing note |
FinancialBreakdown (لاگ مالی)
علاوه بر تسویهحساب دستی، کیفپول نماینده بهصورت خودکار از طریق CommissionService هنگام پرداخت موفقِ نوبت/اشتراک شارژ میشود (WalletTransaction credit). هر واریز یک ردیف FinancialBreakdown ثبت میکند که تفکیک کامل تراکنش (ناخالص، هزینه پیامک، مالیات، خالص، درصد و سهم پورسانت، سهم سیستم) را نگه میدارد. ثبت idempotent است (بر اساس payment_id). گزارشها از طریق GET /api/v1/admin/financial-breakdowns و GET /api/v1/admin/financial-summary در دسترساند — جزئیات در docs/api/admin.md.
رسید پرداخت و ثبت پرداخت نهایی (ROLE_ADMIN)
منطق کیفپول: مبلغ هنگام ثبت درخواست از کیفپول نماینده کسر (reserve/debit) میشود؛ رد آن را برمیگرداند (credit). تأیید و پرداختِ نهایی کیفپول را دوباره دست نمیزنند (جلوگیری از double-debit).
POST /file/upload/clinic_pro/settlement/receipt
آپلود تصویر رسید پرداخت. بدنه = محتوای خام فایل؛ هدر Content-Disposition: filename="...". Permission: ROLE_ADMIN
Response 200:
{ "success": true, "data": { "uuid": "...", "url": "/uploads/settlements/receipts/2026-06/...", "filename": "...", "filemime": "image/jpeg" } }
POST /api/v1/settlement/{uuid}/paid
ثبت پرداخت نهایی با رسید. فقط روی تسویهی approved. وضعیت → paid و receipt ذخیره میشود. کیفپول تغییر نمیکند. Permission: ROLE_ADMIN
Request Body:
{ "receipt": "/uploads/settlements/receipts/2026-06/..." }
| Field | Type | Required | Description |
|---|---|---|---|
receipt |
string | ✅ | URL رسیدِ آپلودشده |
Response 200: آبجکت تسویه (شامل receipt و status: "paid").
Errors:
| Code | HTTP | Description |
|---|---|---|
ERR_NOT_FOUND_001 |
404 | درخواست یافت نشد |
ERR_VALIDATION_001 |
422 | تسویه approved نیست |
ERR_VALIDATION_002 |
422 | receipt خالی (field: receipt) |