feat(payment): add payment detail endpoint and update payment model with order_id and patient_name

feat(appointment): enhance appointment detail page with time formatting and additional info
fix(payment): update payment query to fetch from the correct endpoint and adjust response structure
docs(api): add search parameter to payments API documentation and detail response structure
test(payment): add unit test for MellatGateway to verify null credentials handling
This commit is contained in:
hamed
2026-07-02 15:10:15 +03:30
parent 1e342a695f
commit ca71c49451
8 changed files with 181 additions and 27 deletions
+25 -12
View File
@@ -14,12 +14,15 @@ class MellatGateway implements PaymentGatewayInterface
private readonly HttpClientInterface $httpClient,
private readonly SiteConfigRepository $configRepo,
private readonly LoggerInterface $logger,
private readonly string $terminalId = '',
private readonly string $username = '',
private readonly string $password = '',
private readonly ?string $terminalId = '',
private readonly ?string $username = '',
private readonly ?string $password = '',
) {}
public function getName(): string { return 'mellat'; }
public function getName(): string
{
return 'mellat';
}
public function isConfigured(): bool
{
@@ -28,16 +31,18 @@ class MellatGateway implements PaymentGatewayInterface
&& $this->cfg('mellat_password', $this->password) !== '';
}
private function cfg(string $key, string $envFallback): string
private function cfg(string $key, ?string $envFallback): string
{
return $this->configRepo->get($key) ?: $envFallback;
return (string) ($this->configRepo->get($key) ?: $envFallback ?? '');
}
public function initiate(int $amountRials, string $orderId, string $callbackUrl): PaymentInitResult
{
try {
$response = $this->httpClient->request('POST',
'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl', [
$response = $this->httpClient->request(
'POST',
'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl',
[
'body' => $this->buildRequestPayload($amountRials, $orderId, $callbackUrl),
'headers' => ['Content-Type' => 'text/xml; charset=utf-8'],
'timeout' => 10,
@@ -82,8 +87,10 @@ class MellatGateway implements PaymentGatewayInterface
}
try {
$response = $this->httpClient->request('POST',
'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl', [
$response = $this->httpClient->request(
'POST',
'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl',
[
'body' => $this->buildVerifyPayload($refId),
'headers' => ['Content-Type' => 'text/xml; charset=utf-8'],
'timeout' => 10,
@@ -164,6 +171,12 @@ XML;
return trim($parts[1] ?? '');
}
private function date(): string { return date('Ymd'); }
private function time(): string { return date('His'); }
private function date(): string
{
return date('Ymd');
}
private function time(): string
{
return date('His');
}
}
+7 -4
View File
@@ -15,19 +15,22 @@ class SepGateway implements PaymentGatewayInterface
private readonly HttpClientInterface $httpClient,
private readonly SiteConfigRepository $configRepo,
private readonly LoggerInterface $logger,
private readonly string $terminalId = '',
private readonly ?string $terminalId = '',
) {}
public function getName(): string { return 'sep'; }
public function getName(): string
{
return 'sep';
}
public function isConfigured(): bool
{
return $this->cfg('sep_terminal_id', $this->terminalId) !== '';
}
private function cfg(string $key, string $envFallback): string
private function cfg(string $key, ?string $envFallback): string
{
return $this->configRepo->get($key) ?: $envFallback;
return (string) ($this->configRepo->get($key) ?: $envFallback ?? '');
}
public function initiate(int $amountRials, string $orderId, string $callbackUrl): PaymentInitResult