feat(payment): add refund and reversal functionality to payment gateways

- Implemented `refund` and `reverse` methods in `PaymentGatewayInterface`.
- Added `PaymentRefundResult` class to handle refund operation results.
- Enhanced `MockGateway` and `SepGateway` to support refund and reversal operations.
- Updated `PaymentManager` to include `refundPayment` and `reversePayment` methods for handling refunds and reversals in transactions.
- Modified `ClinicSubscriptionRepository` and `SubscriptionService` to manage subscriptions during refunds.
- Added admin API endpoints for processing refunds and reversals.
- Updated security headers to allow form actions to the sandbox environment.
- Documented the new refund and reversal features in the API documentation.
This commit is contained in:
hamed
2026-07-02 18:45:34 +03:30
parent 6bb47d343d
commit 1b171a82f4
20 changed files with 1111 additions and 21 deletions
+29 -1
View File
@@ -647,6 +647,7 @@ List all payments.
"gateway": "mellat",
"type": "appointment",
"ref_id": "1234567",
"card_pan": "502229******2928",
"patient_mobile": "0912...",
"patient_name": "علی احمدی",
"appointment_uuid": "...",
@@ -656,10 +657,37 @@ List all payments.
}
```
### Errors
> `card_pan` شمارهٔ کارت ماسک‌شدهٔ پرداخت‌کننده (۶ رقم اول + ۴ رقم آخر) است که درگاه در callback برمی‌گرداند (ملت: `CardHolderPan`) و در `metadata.card_pan` پرداخت ذخیره می‌شود؛ اگر درگاه آن را نفرستد `null`. `refunds[]` تاریخچهٔ استردادها (`amount` ریال، `ref` شماره پیگیری، `at` unix).
### POST `/api/v1/admin/payments/{uuid}/refund`
استرداد وجه یک پرداخت **موفق** (کل یا جزئی). فقط `ROLE_ADMIN`. فقط درگاه ملت پشتیبانی می‌شود (سپ خطا می‌دهد).
**Request body:**
| فیلد | نوع | توضیح |
|------|-----|-------|
| `amount` | integer? | مبلغ استرداد به **ریال**. اگر ندهی = کل باقی‌ماندهٔ قابل استرداد. |
استرداد جزئی چندباره مجاز است تا سقف مبلغ خرید. استرداد کامل (رسیدن جمع به مبلغ کل) وضعیت را `refunded` می‌کند.
**Response 200:**
```json
{ "success": true, "data": { "status": "refunded", "refund_ref": "183800538958" } }
```
> کد `0` درگاه ملت فقط «پذیرش اولیهٔ درخواست استرداد» است؛ عودت نهایی به کارت ممکن است چند روز طول بکشد.
### POST `/api/v1/admin/payments/{uuid}/reverse`
برگشت وجه یک پرداخت **موفقِ settle‌نشده** (بدون body). فقط `ROLE_ADMIN`. در موفقیت وضعیت `refunded`.
**Response 200:** `{ "success": true, "data": { "status": "refunded" } }`
### Errors (payment refund/reverse/detail)
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_NOT_FOUND_001` | 404 | پرداخت یافت نشد |
| `ERR_PAYMENT_002` | 422 | مبلغ نامعتبر / پرداخت غیرقابل استرداد / درگاه پشتیبانی نمی‌کند |
---