feat: implement tax calculations for subscription and SMS wallet payments
- Updated SubscriptionPeriod interface to include tax-related fields: tax_percent, tax_rials, and payable_rials. - Modified payment API documentation to reflect changes in tax handling for subscriptions and SMS wallet charges. - Adjusted PaymentController to calculate payment amounts based on subscription period details instead of client input. - Enhanced PaymentManager to handle net amounts for SMS wallet charges, ensuring tax is not credited to the wallet. - Created PaymentTaxCalculator and SubscriptionTaxCalculator services to manage tax calculations consistently across payment types. - Added tests for tax calculations in both subscription and SMS wallet contexts, ensuring correct behavior with and without tax enabled. - Updated frontend components to display tax information appropriately during payment processes.
This commit is contained in:
+10
-3
@@ -106,7 +106,8 @@
|
||||
"appointment_fee_rials": 150000,
|
||||
"gateways": [
|
||||
{ "name": "mellat", "label": "بانک ملت" }
|
||||
]
|
||||
],
|
||||
"tax_percent": 10
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -116,6 +117,7 @@
|
||||
| `test_mode` | boolean | `true` = درگاه آزمایشی فعال است — backend از MockGateway استفاده میکند و پول واقعی کسر نمیشود |
|
||||
| `appointment_fee_rials` | integer | مبلغ هر نوبت به ریال (از تنظیمات سایت، کلید `appointment_fee_rials`). frontend برای نمایش «مبلغ قابل پرداخت» از این میخواند؛ مبلغِ واقعیِ تراکنش هم در backend از همین کلید خوانده میشود (نه از client) |
|
||||
| `gateways` | array | فقط درگاههای **فعال** (اعتبارنامهشان در تنظیمات سایت یا env ست شده). هر عضو: `{ name, label }`. frontend فقط همینها را برای انتخاب نمایش میدهد. در `test_mode` تنها `[{ "name": "mellat", "label": "بانک ملت (آزمایشی)" }]` برمیگردد. اگر هیچ درگاهی فعال نباشد آرایه خالی است و frontend باید پرداخت را غیرفعال کند. |
|
||||
| `tax_percent` | number | نرخ مالیات بر ارزش افزوده برای **اشتراک** و **شارژ کیف پول پیامک**. صفر یعنی مالیات خاموش است (`tax_enabled=0`). frontend با این عدد جمع کل را پیش از ارسال درخواست نشان میدهد؛ مبلغ نهایی همیشه در backend دوباره حساب میشود. نوبت این نرخ را به این شکل بهکار نمیبرد — آنجا مبلغ شامل مالیات است. |
|
||||
|
||||
فعالبودن هر درگاه با `PaymentGatewayInterface::isConfigured()` **و** کلید فعالسازی در تنظیمات سایت تعیین میشود: `mellat` نیازمند `mellat_terminal_id` + `mellat_username` + `mellat_password`؛ `sep` نیازمند `sep_terminal_id`. علاوه بر این، اگر ادمین درگاه را در تنظیمات غیرفعال کند (`mellat_enabled` / `sep_enabled` = `"0"`)، آن درگاه از این لیست حذف میشود و در `initiate` نیز رد میشود (خطای ۴۲۲: «درگاه پرداخت نامعتبر یا غیرفعال است»). کلید تنظیمنشده = فعال (پیشفرض).
|
||||
|
||||
@@ -341,7 +343,7 @@ Initiate a subscription / wallet top-up payment (not tied to a specific appointm
|
||||
```json
|
||||
{
|
||||
"gateway": "mellat",
|
||||
"amount_rials": 1000000,
|
||||
"period_uuid": "uuid-of-subscription-period",
|
||||
"frontend_address": "https://myapp.com/wallet/result"
|
||||
}
|
||||
```
|
||||
@@ -349,9 +351,14 @@ Initiate a subscription / wallet top-up payment (not tied to a specific appointm
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `gateway` | string | ✅ | `"mellat"` or `"sep"` |
|
||||
| `amount_rials` | integer | ✅ | Amount in Rials (min: 10,000) |
|
||||
| `period_uuid` | string | ✅ | دورهٔ اشتراک؛ مبلغ از آن محاسبه میشود |
|
||||
| `frontend_address` | string | ❌ | Redirect URL after payment |
|
||||
|
||||
> `amount_rials` دیگر خوانده نمیشود. مبلغ = `price_rials + tax_rials` همان دوره، محاسبهشده در
|
||||
> `SubscriptionTaxCalculator`. قیمت دوره خالص است و مالیات رویش اضافه میشود — جزئیات در
|
||||
> [subscription.md](subscription.md#مالیات-دورهها). پاسخ هم هر چهار عدد را برمیگرداند:
|
||||
> `price_rials`، `tax_percent`، `tax_rials`، `payable_rials`.
|
||||
|
||||
### Response `200`
|
||||
```json
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user