- Add ZarinpalService for production payment gateway - Add MockZarinpalService for testing without real merchant ID - Add MockGatewayController for simulating payment page - Add beautiful mock gateway UI with RTL support - Update PaymentController to switch between mock/real based on config - Fix double-click bug: prevent re-processing completed transactions - Add payment-result page with success/failure UI - All API endpoints tested successfully: * balance, transactions, activity-log * admin-adjust (deposit/withdrawal) * freeze/unfreeze * online payment redirect + callback + verify - Wallet balance verified: 67,700,000 IRR after all transactions - 5 transactions recorded with correct gateways (manual/zarinpal) Closes: Payment gateway integration for Phase 2
52 lines
1.4 KiB
PHP
52 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Str;
|
|
|
|
class MockZarinpalService
|
|
{
|
|
public function requestPayment(
|
|
float $amount,
|
|
string $description,
|
|
?string $mobile = null,
|
|
?string $email = null
|
|
): array {
|
|
$authority = 'MOCK_' . Str::upper(Str::random(32));
|
|
|
|
Log::info('Mock Zarinpal Payment Request', [
|
|
'amount' => $amount,
|
|
'authority' => $authority,
|
|
]);
|
|
|
|
return [
|
|
'authority' => $authority,
|
|
'payment_url' => url("/api/v1/payment/mock-gateway?authority={$authority}&amount={$amount}"),
|
|
'amount' => $amount,
|
|
'amount_toman' => (int) round($amount / 10),
|
|
];
|
|
}
|
|
|
|
public function verifyPayment(string $authority, float $expectedAmount): array
|
|
{
|
|
Log::info('Mock Zarinpal Payment Verification', [
|
|
'authority' => $authority,
|
|
]);
|
|
|
|
if (str_starts_with($authority, 'MOCK_')) {
|
|
return [
|
|
'success' => true,
|
|
'ref_id' => 'MOCK_REF_' . Str::upper(Str::random(16)),
|
|
'card_hash' => 'MOCK_HASH_' . rand(100000, 999999),
|
|
'card_pan' => '6037****' . rand(1000, 9999),
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => false,
|
|
'error_code' => -1,
|
|
'error_message' => 'Authority نامعتبر است',
|
|
];
|
|
}
|
|
} |