feat(payment): enhance payment flow with new pay endpoint and POST redirect method
This commit is contained in:
+28
-3
@@ -107,12 +107,14 @@ Initiate payment for an appointment. Returns a redirect URL to the payment gatew
|
||||
"success": true,
|
||||
"data": {
|
||||
"payment_uuid": "pay-uuid-...",
|
||||
"redirect_url": "https://bpm.shaparak.ir/pgwchannel/...",
|
||||
"order_id": "CLINICPRO-1717000000-ABC123"
|
||||
"pay_url": "{APP_BASE_URL}/api/v1/payment/pay/ORD-XXXX",
|
||||
"order_id": "ORD-XXXX"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **جریان انتقال به درگاه:** این endpoint فقط **صلاحیت اوردر** را بررسی و یک پرداختِ `pending` میسازد؛ **هیچ ارتباطی با بانک برقرار نمیکند**. کلاینت باید مرورگر را به `pay_url` هدایت کند. سپس `GET /api/v1/payment/pay/{orderId}` (سمت بکاند) درگاه را init میکند (ارتباط با بانک) و مرورگر را به درگاه میفرستد (302 برای درگاههای GET مثل سپ، یا فرم auto-submit با متد POST برای درگاه ملت). به این ترتیب کلاینت هرگز مستقیم به بانک ریکوست نمیزند.
|
||||
>
|
||||
> **مبلغ نوبت:** مبلغِ پرداخت از کلید `appointment_fee_rials` تنظیمات سایت خوانده میشود (نه از client و نه hardcode). برای تغییر، در `/admin/settings` ویرایش کنید.
|
||||
>
|
||||
> **On successful callback** for an appointment payment, the booking is transitioned `pending → confirmed` (its 15-minute `expires_at` is cleared) and a confirmation SMS is dispatched to the patient's mobile. تاریخِ نوبت در متن پیامک بهصورت **شمسی** (`JalaliDateService::formatDateTime`، مثل `۱۴۰۵/۰۴/۰۲ ۰۹:۰۰`) درج میشود. If the booking already lapsed to `expired` before payment confirmed, it is **not** re-confirmed (the transition is rejected) — handle refund out of band.
|
||||
@@ -126,7 +128,30 @@ Initiate payment for an appointment. Returns a redirect URL to the payment gatew
|
||||
| `ERR_FORBIDDEN_001` | 403 | Not the patient |
|
||||
| `ERR_PAYMENT_003` | 422 | Appointment not in payable state |
|
||||
| `ERR_PAYMENT_002` | 422 | Invalid amount |
|
||||
| `ERR_PAYMENT_001` | 503 | Payment gateway unavailable |
|
||||
| `ERR_VALIDATION_001` | 422 | درگاه پرداخت نامعتبر یا غیرفعال / آدرس بازگشت مجاز نیست |
|
||||
|
||||
---
|
||||
|
||||
## GET `/api/v1/payment/pay/{orderId}`
|
||||
|
||||
انتقال مرورگر به درگاه پرداخت برای یک پرداختِ `pending`. **عمومی (بدون JWT)** — مرورگر مستقیماً به این آدرس هدایت میشود. صلاحیت اوردر قبلاً در `POST /api/v1/payment/appointment` (نیازمند JWT) بررسی و پرداخت ساخته شده است. **ارتباط با بانک (init درگاه) در همین endpoint انجام میشود.**
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `orderId` | string | `order_id` پرداخت (از پاسخ initiate) |
|
||||
|
||||
### رفتار
|
||||
- اگر پرداخت یافت نشد → `404 { success:false, message:"payment not found" }`.
|
||||
- اگر وضعیت پرداخت `pending` نباشد → `302` به `frontend_address` با نتیجه (جلوگیری از پرداخت تکراری).
|
||||
- درگاه resolve میشود (در حالت تست → mock)؛ اگر نامعتبر بود یا circuit breaker باز بود → پرداخت `failed` و `302` به `frontend_address`.
|
||||
- `gateway->initiate(...)` صدا زده میشود (ارتباط با بانک). در صورت شکست → `failed` و `302` به `frontend_address`.
|
||||
- در صورت موفقیت: توکن ذخیره و انتقال به درگاه:
|
||||
- متد `GET` (سپ/mock) → `302` به URL درگاه.
|
||||
- متد `POST` (ملت) → صفحهٔ HTML با فرم **auto-submit** (POST) به درگاه، شامل فیلدهای لازم (مثل `RefId`).
|
||||
|
||||
### Permission
|
||||
`PUBLIC` (در `security.yaml` تحت firewall `payment_callback` و access_control عمومی).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user