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:
@@ -40,6 +40,7 @@ class SmsWalletController extends BaseController
|
||||
private readonly \App\Config\Repository\SiteConfigRepository $configRepo,
|
||||
private readonly \App\Secretary\Security\SecretaryAccessChecker $secretaryAccess,
|
||||
private readonly \App\Clinic\Security\ClinicDoctorAccessChecker $clinicDoctorAccess,
|
||||
private readonly \App\Payment\Service\PaymentTaxCalculator $tax,
|
||||
private readonly string $appBaseUrl,
|
||||
) {}
|
||||
|
||||
@@ -82,12 +83,18 @@ class SmsWalletController extends BaseController
|
||||
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
$gatewayName = trim($data['gateway'] ?? 'mellat');
|
||||
$amountRials = (int) ($data['amount_rials'] ?? 0);
|
||||
// `amount_rials` مبلغی است که به کیف پول مینشیند — خالص، بدون مالیات.
|
||||
$netRials = (int) ($data['amount_rials'] ?? 0);
|
||||
|
||||
if ($amountRials <= 0) {
|
||||
if ($netRials <= 0) {
|
||||
return $this->error(ErrorCodes::ERR_PAYMENT_002, 'مبلغ شارژ نامعتبر است', 422);
|
||||
}
|
||||
|
||||
// مالیات روی مبلغ شارژ اضافه میشود؛ اعتبارِ کیف پول همان مبلغ خالص میماند،
|
||||
// وگرنه کاربر مالیات را هم بهصورت اعتبار پیامک پس میگرفت.
|
||||
$breakdown = $this->tax->breakdown($netRials);
|
||||
$amountRials = $breakdown['payable_rials'];
|
||||
|
||||
// فقط اعتبارسنجی درگاه؛ ارتباط با بانک در flow واحد (GET /payment/pay) انجام میشود.
|
||||
if ($this->gateways->resolve($gatewayName) === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'درگاه پرداخت نامعتبر است', 422);
|
||||
@@ -96,14 +103,19 @@ class SmsWalletController extends BaseController
|
||||
$frontendAddress = trim($data['frontend_address'] ?? '');
|
||||
$payment = new Payment($user, $amountRials, $gatewayName, Payment::TYPE_SMS_WALLET, $frontendAddress);
|
||||
$payment->assignTenantPair($entityType, $entityId);
|
||||
$payment->setMetadata(['entity_type' => $entityType, 'entity_id' => $entityId]);
|
||||
$payment->setMetadata([
|
||||
'entity_type' => $entityType,
|
||||
'entity_id' => $entityId,
|
||||
// اعتباری که بعد از پرداخت موفق به کیف پول مینشیند — بدون مالیات.
|
||||
'net_rials' => $netRials,
|
||||
]);
|
||||
$this->paymentRepo->save($payment);
|
||||
|
||||
return $this->success([
|
||||
'payment_uuid' => $payment->getUuid(),
|
||||
'pay_url' => $this->appBaseUrl . '/api/v1/payment/pay/' . $payment->getOrderId(),
|
||||
'order_id' => $payment->getOrderId(),
|
||||
]);
|
||||
] + $breakdown);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/sms/wallet/logs', methods: ['GET'])]
|
||||
|
||||
Reference in New Issue
Block a user