Fix ABHA card fetch and address suggestions

This commit is contained in:
DevSoftTech Server 2026-08-13 17:41:31 +05:30
parent 3e70ff8c4a
commit d0a0bf984e
2 changed files with 68 additions and 61 deletions

View File

@ -142,8 +142,8 @@ class Abha extends BaseController
'ok' => 1, 'ok' => 1,
'txn_id' => $newTxnId, 'txn_id' => $newTxnId,
'skip_mobile' => true, 'skip_mobile' => true,
'card_base64' => $this->extractAbhaCardData($payload), 'card_base64' => $this->extractAbhaCardData($result),
'card_content_type' => $this->resolveAbhaCardContentType($payload), 'card_content_type' => $this->resolveAbhaCardContentType($result),
'abha_number' => $abhaNum, 'abha_number' => $abhaNum,
'name' => $name, 'name' => $name,
'photo' => $photo, 'photo' => $photo,
@ -305,8 +305,8 @@ class Abha extends BaseController
$responseBase = [ $responseBase = [
'ok' => 1, 'ok' => 1,
'card_base64' => $this->extractAbhaCardData($payload), 'card_base64' => $this->extractAbhaCardData($result),
'card_content_type' => $this->resolveAbhaCardContentType($payload), 'card_content_type' => $this->resolveAbhaCardContentType($result),
'abha_number' => $abhaNum, 'abha_number' => $abhaNum,
'name' => $name, 'name' => $name,
'photo' => $photo, 'photo' => $photo,
@ -2015,7 +2015,8 @@ class Abha extends BaseController
private function resolveAbhaCardContentType(array $payload): string private function resolveAbhaCardContentType(array $payload): string
{ {
$format = strtolower(trim((string) ($payload['card_content_type'] ?? $payload['cardContentType'] ?? $payload['card_format'] ?? ($payload['account']['card_format'] ?? '')))); $data = is_array($payload['data'] ?? null) ? $payload['data'] : [];
$format = strtolower(trim((string) ($payload['card_content_type'] ?? $payload['cardContentType'] ?? $payload['card_format'] ?? ($payload['account']['card_format'] ?? '') ?: ($data['card_format'] ?? ''))));
if ($format === 'png') { return 'image/png'; } if ($format === 'png') { return 'image/png'; }
if ($format === 'jpg' || $format === 'jpeg') { return 'image/jpeg'; } if ($format === 'jpg' || $format === 'jpeg') { return 'image/jpeg'; }
if ($format === 'pdf') { return 'application/pdf'; } if ($format === 'pdf') { return 'application/pdf'; }

View File

@ -698,13 +698,54 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
return $result; return $result;
} }
return $this->attachOfficialAbhaCard($result);
}
/**
* Ensure a verify/enrol response carries the official ABHA card, fetching it
* from the Bridge card endpoint when the response itself omits it.
*
* @param array<string, mixed> $result
* @return array<string, mixed>
*/
private function attachOfficialAbhaCard(array $result): array
{
$data = is_array($result['data'] ?? null) ? $result['data'] : []; $data = is_array($result['data'] ?? null) ? $result['data'] : [];
$account = is_array($result['account'] ?? null) $account = is_array($result['account'] ?? null)
? $result['account'] ? $result['account']
: (is_array($data['account'] ?? null) ? $data['account'] : []); : (is_array($data['account'] ?? null) ? $data['account'] : []);
$abhaNumber = trim((string) ($account['ABHANumber'] ?? $account['abhaNumber'] ?? $account['abha_id'] ?? $data['ABHANumber'] ?? $data['abhaNumber'] ?? $data['abha_id'] ?? '')); $profile = is_array($data['ABHAProfile'] ?? null) ? $data['ABHAProfile'] : [];
$abhaAddress = trim((string) ($account['abhaAddress'] ?? $account['preferredAddress'] ?? $account['abha_address'] ?? $data['abhaAddress'] ?? $data['preferredAddress'] ?? $data['abha_address'] ?? '')); $abhaNumber = trim((string) ($account['ABHANumber'] ?? $account['abhaNumber'] ?? $account['abha_id'] ?? $data['ABHANumber'] ?? $data['abhaNumber'] ?? $data['abha_id'] ?? $profile['ABHANumber'] ?? $profile['abha_id'] ?? ''));
$extractCard = static function (array $source): string { $abhaAddress = trim((string) ($account['abhaAddress'] ?? $account['preferredAddress'] ?? $account['abha_address'] ?? $data['abhaAddress'] ?? $data['preferredAddress'] ?? $data['abha_address'] ?? $profile['preferredAbhaAddress'] ?? $profile['abhaAddress'] ?? ''));
$card = $this->extractOfficialCard($result)
?: $this->extractOfficialCard($data)
?: $this->extractOfficialCard($account)
?: $this->extractOfficialCard($profile);
if ($card === '' && ($abhaNumber !== '' || $abhaAddress !== '')) {
$cardResult = $this->get('/v3/abha/card', array_filter([
'abha_number' => $abhaNumber,
'abha_address' => $abhaAddress,
], static fn($value): bool => trim((string) $value) !== ''));
if (! empty($cardResult['ok']) && (int) $cardResult['ok'] === 1) {
$cardData = is_array($cardResult['data'] ?? null) ? $cardResult['data'] : $cardResult;
$card = $this->extractOfficialCard($cardData);
if ($card !== '') {
$result['card_base64'] = $card;
$result['card_content_type'] = $this->resolveCardContentType($cardData);
}
}
}
return $result;
}
/**
* @param array<string, mixed> $source
*/
private function extractOfficialCard(array $source): string
{
foreach (['card_base64', 'card_data', 'abhaCard', 'abha_card', 'official_card', 'cardData', 'card'] as $key) { foreach (['card_base64', 'card_data', 'abhaCard', 'abha_card', 'official_card', 'cardData', 'card'] as $key) {
$value = $source[$key] ?? ''; $value = $source[$key] ?? '';
if (is_string($value) && trim($value) !== '') { if (is_string($value) && trim($value) !== '') {
@ -718,26 +759,8 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
} }
} }
} }
return ''; return '';
};
$card = $extractCard($result) ?: $extractCard($data) ?: $extractCard($account);
if ($card === '' && ($abhaNumber !== '' || $abhaAddress !== '')) {
$cardResult = $this->get('/v3/abha/card', array_filter([
'abha_number' => $abhaNumber,
'abha_address' => $abhaAddress,
], static fn($value): bool => trim((string) $value) !== ''));
if (! empty($cardResult['ok']) && (int) $cardResult['ok'] === 1) {
$cardData = is_array($cardResult['data'] ?? null) ? $cardResult['data'] : $cardResult;
$card = $extractCard($cardData);
if ($card !== '') {
$result['card_base64'] = $card;
$result['card_content_type'] = $this->resolveCardContentType($cardData);
}
}
}
return $result;
} }
private function resolveCardContentType(array $payload): string private function resolveCardContentType(array $payload): string
@ -781,7 +804,13 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
if ($this->hfrId !== '' && empty($body['hfr_id'])) { if ($this->hfrId !== '' && empty($body['hfr_id'])) {
$body['hfr_id'] = $this->hfrId; $body['hfr_id'] = $this->hfrId;
} }
return $this->post('/v3/abha/aadhaar/verify-otp', $body);
$result = $this->post('/v3/abha/aadhaar/verify-otp', $body);
if (empty($result['ok']) || (int) $result['ok'] !== 1) {
return $result;
}
return $this->attachOfficialAbhaCard($result);
} }
public function abhaMobileGenerateOtp(array $payload): array public function abhaMobileGenerateOtp(array $payload): array
@ -813,16 +842,8 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
public function abhaAddressSuggestions(array $payload): array public function abhaAddressSuggestions(array $payload): array
{ {
$txnId = (string) ($payload['txn_id'] ?? $payload['txnId'] ?? ''); $txnId = (string) ($payload['txn_id'] ?? $payload['txnId'] ?? '');
$body = ['txn_id' => $txnId, 'txnId' => $txnId];
if ($this->hfrId !== '') {
$body['hfr_id'] = $this->hfrId;
}
$result = $this->postFirstAvailable([ $result = $this->get('/v3/abha/suggestions', ['txnId' => $txnId]);
'/v3/abha/enrollment/suggestion',
'/v3/abha/address/suggestion',
'/v3/abha/enrol/suggestion',
], $body);
if (empty($result['ok']) || (int) $result['ok'] !== 1) { if (empty($result['ok']) || (int) $result['ok'] !== 1) {
return $result; return $result;
@ -837,39 +858,24 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
{ {
$txnId = (string) ($payload['txn_id'] ?? $payload['txnId'] ?? ''); $txnId = (string) ($payload['txn_id'] ?? $payload['txnId'] ?? '');
$address = (string) ($payload['abha_address'] ?? $payload['abhaAddress'] ?? ''); $address = (string) ($payload['abha_address'] ?? $payload['abhaAddress'] ?? '');
// ABDM expects the handle without the @provider suffix.
$address = explode('@', $address)[0];
$body = [ $body = [
'txn_id' => $txnId,
'txnId' => $txnId, 'txnId' => $txnId,
'abha_address' => $address,
'abhaAddress' => $address, 'abhaAddress' => $address,
'preferred' => 1,
]; ];
if ($this->hfrId !== '') { if ($this->hfrId !== '') {
$body['hfr_id'] = $this->hfrId; $body['hfr_id'] = $this->hfrId;
} }
return $this->postFirstAvailable([ $result = $this->post('/v3/abha/set-address', $body);
'/v3/abha/enrollment/abha-address',
'/v3/abha/address/set',
'/v3/abha/enrol/abha-address',
], $body);
}
/** if (! empty($result['ok']) && (int) $result['ok'] === 1) {
* Bridge path naming for newer endpoints is still settling; try each $data = is_array($result['data'] ?? null) ? $result['data'] : [];
* candidate and keep the first response that is not a 404/405. $preferred = trim((string) ($data['preferredAbhaAddress'] ?? $data['preferred_abha_address'] ?? $data['abhaAddress'] ?? ''));
* if ($preferred !== '') {
* @param string[] $paths $result['abha_address'] = $preferred;
* @param array<string, mixed> $body
* @return array<string, mixed>
*/
private function postFirstAvailable(array $paths, array $body): array
{
$result = ['ok' => 0, 'http_code' => 404, 'error_text' => 'Endpoint not available on the ABDM Bridge.'];
foreach ($paths as $path) {
$result = $this->post($path, $body);
if (! in_array((int) ($result['http_code'] ?? 0), [404, 405], true)) {
return $result;
} }
} }